Search This Blog

15 December 2010

Namespaces in Aif Xml-messages

In a previous posting I described the structure of a Dynamics Ax 2009 Aif message. Here now some information about Namespaces in Aif Xml-messages:

An Aif Xml message is identified by namespaces on 3 locations:
- the Xml-envelope (1)
- the Aif-service (2)
- the Xml-messageparts (3) + (4)

According to my previous posting:


These information are defined in Ax in the following places:

Macros
Aif: (1) + (3)
#define.MessageNamespace ('http://schemas.microsoft.com/dynamics/2008/01/documents/Message')
#define.EntityKeyNamespace ('http://schemas.microsoft.com/dynamics/2006/02/documents/EntityKey')
#define.EntityKeyListNamespace ('http://schemas.microsoft.com/dynamics/2006/02/documents/EntityKeyList')

Axd: (3) used as standard namespace for all Axd-documents by default:
#define.DocumentNameSpace('http://schemas.microsoft.com/dynamics/2008/01/documents')

Services nodes (2) as described on msdn



X++ (4) the default Axd-document namespace in the AxdBase-class by the getNamespace()-method


(4) if the Axd-document namespace can be overridden in the Axd-class:

11 November 2010

AIF surprises with verbose responses...

The title could also be "AIF security whole", but I choosed the understatement ;-)

Using QueryCriteria to filter can result in returning all data it you do an error in your request. To describe this, lets take the standard AddressService and do a find request by using the FileSystemAdapter. Here's a correct requst example:


 
{DD112222-0306-1220-0001-DD33444455DD} DYNAMICS\Administrator Sample Contoso http://schemas.microsoft.com/dynamics/2008/01/services/AddressService/find
Address Name Equal Sit*

Now the QueryCriteria does contain an error (I removed the CriteriaElement):


 
{DD112222-0306-1220-0001-DD33444455DD} DYNAMICS\Administrator Sample Contoso http://schemas.microsoft.com/dynamics/2008/01/services/AddressService/find
Address Name Equal Sit*

Normally this cannot be validated because it is not conform to the schema
defined in the QueryCriteria.xsd. The QueryCriteria elemet riquires to have at least one CriteriaElement:




                
    
    
        
            
        
    

    
        
            
            
            
            
            
        
    

    
        
            
            
            
            
            
            
            
        
    



But instead of not validating the document of the request, AIF decides to return all data. This behavior can be reproduced on any standard or custom AIF document service.

It is very likely that the Aif-services do not validate incoming Xml messages (as it is configurable for outgoing messages!) for performance reasons, but it should be possible to configure this nevertheless.

08 November 2010

Dyanmics Ax 2009 AIF message

Here is a simple schema of the AIF message structure based on the Dynamics Ax 2009 AIF Xsd-schemas:The two principle elements of an AIF message are the message header and the message body.
All elements in the schema with exception of the "any" element (part of the message body) are explicitly defined by a Microsoft namespace (like http://schemas.microsoft.com/dynamics/...). The custom schema (by default deduced from the document underlying query) need to be explicitly defined by its own namespace. A namespace will define the service by default by its editor (like schemas.microsoft.com), its version (defined by its creation date: yyy/mm) and its purpose: the name of the service. This might be for example: http://yourcompany.com/2010/11/services/YourCustomService
The AIF actions are associated to the namespace of the message. A message header might for example look like this:
{3B7C23AB-B0EF-4C35-8DC6-481574080F62} Default Default http://yourcompany.com/2010/11/services/YourCustomService/read {C8111B69-9786-4BB4-9A03-D0BE847F4C3C}

11 October 2010

Listing changed objects in a rollup

Once a rollup archive has been decompressed, a manifest file is accessible in the root-directory of the extracted files. In the RU5 for the SP1 (KB982812) this file is called “dynamicsax2009-kb982812-sp1-manifest.xml”. So far so good. Unfortunately this manifest file can be very large and is over 1GB for the RU. This because the file contains not only the changes, but also all dependencies, with makes this file so verbose.
The TransformTool is very simple tool and might help you working with these data by transforming the original manifest data into a much less verbose xml-file:

02 July 2010

Configuring AIF WebServices with mapped x.509 certificates

AIF WebServices needs to be authenticated with a Windows user that is configured in Ax. This can be done with Ntlm authentication. If the Ntlm-authentication is not an option, the X.509 authentication can be an alternative. X.509 certificates can be mapped easily to a windows account and so makes it possible for the client to authenticate as an Windows-user.

The following snapshots can serve as a simple “how-to”-setup the X.509 certificates for the AIF-WebServices.

The IIS-configuration

The anonymous access need to be activated:

image

The client certificate mapping needs to be activated:

image

After selecting the certificate, the certificate needs to be mapped to the Windows-account:

image

image

The service configuration:

The service configuration is configured to authenticate on the transport level:

image

and the MapClientCertificateToWindowsAccount attribute is activated:

image

The client configuration:

The client authentication is configured for transport:

image

And the configuration points to the X.509 certificate. The clientCertificate-element is documented on msdn.

image

If your are using a dummy-certificate, you need to implement the RemoteCertificateValidationCallback in the client application as described in this article.

01 July 2010

Testing AIF-WebServices with soapUI

The open-source project soapUI (from eviware) is probably the most complete and easiest to use soap testing suite and it’s free. It is a great tool to test AIF-WebServices, too.
Authenticating AIF-Services is in most cases configured to be authenticated with Windows credentials and so with NTLM. So far soapUI only supports NTLMv1 and because of this you need to be sure that your server does support the NTLMv1 which is configured with the LmCompatibilityLevel property in the HKLM\SYSTEM\CurrentControlSet\Control\Lsa hive.
Configuring soapUI for authenticating with Ntlm is quite easy and well documented.
To authenticate with Ntlm to an AIF-WebService you just need to configure the username, password and domain:
image
and the WS-A the default wsa:To:
image
On the server side the binding needs to be configured for Ntlm-authentication on transport level. This is by default set to “Windows”:
image
Now soapUI can consume the AIF-WebService:
image

Limitations of the Dynamics Ax Service references

Service references are WebService Proxies generated by Ax 2009 with the tool svcutil.exe based on Wsdl files. Creating a Service reference is very easy and well documented on msdn and it was never been easier to consume WebServices with X++ if the Wsdl of the WebService is compatible with Dynamics Ax. Wsdl files are normally generated by the WebService which is in almost every case based on a SOAP engines like the Cape Clear or Axis. These ‘Service References’ are providing the interoperability between the WebService and Dynamics Ax 2009 as consumer (see ‘consume a WebService from X++’ and the whitepaper). There are some comatibility limitations known:

  1. No support for SOAP headers
  2. Client-code must be executed on the server (AOS)
  3. Limited authentication support (you cannot authenticate with a different user account) due the missing impersonation support on the AOS
  4. Service references only support Wsdl with only one service group
  5. Only services with Document/literal binding style

You can workaround these limitations (Points 1-4) by creating manually the WebService-proxy as it was necessary with Dynamics 4 with the wsdl.exe tool.

Regarding point 5, the workaround can be writing a custom WebService proxy or to ask the WebService provider to expose his service with Document/literal style. WebService-Server such as Axis do support both types, so it might be possible to change the configuration on the server side. The article from Russell Butek describes and compares the possible choices.

If it is not possible to change the binding-style (for example if the service is using overloaded methods or if the provider refuses is), the only possible workaround is to create manually the WebService-proxy then to decorate the WebMethod with the SoapRpcMethod-Attribute and to reference this assembly as it was done for Dynamics Ax4. This because neither the asmx.exe tool (ASP.Net-WebServices), nor the svcutil.exe (WCF-Services) do support the RPC-binding-style.

A great source of knowledge about the interoperability between .Net and WebSphere is the IBM Redbook (WebSphere and .Net Interoperability Using Web Services) and the msdn article about customizing SOAP Formatting.

30 June 2010

Cross domain access to AIF WebServices (Dynamics Ax 2009)

AIF-WebServices need to authenticated with a Windows user that is configured as an Ax user. This is no problem if the client is written in .Net (by using the WCF).

WCF-client

If the client application calls the AIF-WebService within the same domain, it will authenticate implicitly with the current user (as described on msdn). The authentication can de done on the transport or/and the message level. Transport means, that the IIS will do the http authentication, message means, that the WCF authenticates the message.  The service configuration (web.config) of the AIF WebService might look like this when you activate both authentication modes with Windows-credentials:

image

On the client side, the authentication will be completely transparent in the source-code, and the client–configuration (app.config) would look like this:

image

Consuming the AIF-WebServices from a different domain requires explicit credentials for the service-proxy (client):

A01ServiceServiceClient proxy = new A01ServiceServiceClient();
proxy.ClientCredentials.Windows.ClientCredential.Domain = "CONTOSO";
proxy.ClientCredentials.Windows.ClientCredential.UserName = "Administrator";
proxy.ClientCredentials.Windows.ClientCredential.Password = "pass@word1";
string message = proxy.HelloWorld("toto");
proxy.Close();

The clientCredentialType needs to be set to Ntlm in the app.config:

image

This example was configured to use the wsHttpBinding, which is the the binding that is conform to the WS-I and that enables the SOAP-header information such as DestinationEndpoint. This is not the default binding configuration. Unfortunately this is basicHttpBinding which is not compliant to the WS-I standard and does not support the SOAP-headers as it does the wsHttpBinding but it is compatible to the former ASP.Net WebServices (asmx-services) that were used by Dynamics Ax 4. There is a good article on CodeProject that explains the differences of both binding-type.

Non WCF-client in a different domain

Using non WCF applications as a client might be different, as many platforms do not support the Windows-authentication. In most of the cases it is good enough to use instead of this the Username authentication or use X.509 certificates. Both scenarios require a SSL. A good documentation about how to configure this is available on msdn. I will publish a “how-to” for using X.509 certificates for this purpose in a near future. If you are not using the old-style ASP.NET WebServices, you should in any case use the wsHttpBinding. There is no disadvantage to change the default-setting to this.

In some scenario it might be possible that the platform of the client-application does not support these modes and in these cases it would require an additional “proxy-service” that interacts as a trusted intermediary:

The trusted intermediary is a logical intermediary between the document request originating party (external endpoint) and AIF. The trusted intermediary is authorized to submit inbound requests on behalf of the external endpoint. The trusted intermediary must be an internal account. For more information, see Considerations for the endpoint user configuration.

This proxy-WebService should use the WCF for the communication with the AIF-WebService, because it makes it easier to authenticate securely with the AIF-WebService (Windows authentication). Such a proxy-WebService can be installed on the client-side:

image

or on the AIF-WebService server side:

image

In both cases the client to proxy-WebService authentication can be freely chosen. The Proxy-WebService to AIF-WebService should be configured as wsHttpBinding with Windows authentication. This proxy-WebService has in an extranet scenario the advantage that the AIF-WebService has not to be exposed in the DMZ. Anyway, for security reasons exposing the AIF-WebServices directly in an extranet is a “no-do”:

The AIF security design assumes that all inbound messages come from trusted sources. This means that AIF should not be deployed directly over the Internet or extranets. If AIF messages must be received from endpoints over the Internet, use middleware and trusted intermediaries (Microsoft Dynamics AX users or user groups authorized to act on behalf of an AIF endpoint). 

But not only for security reasons, but this might improve the performance as well, because this additional tier can cache frequently requested data and it is more scalable, because of the missing BC.Net (Business-connector)..

Error: A base address cannot contain a Uri query string. Parameter name: baseAddress

I just spend some hours on a stupid error caused by copy and paste and because I couldn’t find any hint neither on Google nor on our internal KB, I’m logging this. Maybe this can help someone when searching for this error message on Google. Clignement d'œil

Message:

A base address cannot contain a Uri query string. Parameter name: baseAddress

Cause: erroneous serviceMetadata element in the service web.config like this one:

image

Resolution:

configure the attribute with a valid Uri like “https://10.166.3.2/MicrosoftDynamicsAXAif50”.

24 June 2010

.net programming for Dynamics AX developers slides

I saw that I did not upload the slides of my webcast about .Net for X++ programmers last year. Here it is finally :-) It’s the working draft, but because it contains more slides, I’m uploading this.

Consuming an AIF WebServices (wsHttpBinding) with SSL and a dummy certificate

Here’s a quick “How-To” for consuming AIF-WebServices in a wsHttpBinding configuration with SSL and a dummy user. It’s always better to have a small documentation for those kind of tasked and I know that I will forget this in a few days without it. So why not sharing this? :-)1) Implement the SSL in IIS

2) The certification authority needs to be registered on the client:

http://<localhost>/certsrv

image

Save the CA certificate and import this certificate on the client with the certmgr.msc:

image

image

image

3) My AIF WebService in this example is configured for a transport security. Now the WebService is ready to be consumed. Consuming the AIF WebService with transport security requires that the clientCredentialType (line 11 in the following app.config excerpt)) attribute of the Transport element is set to “Ntlm”. By default this is set to “Windows”. The desciption for this attribute on msdn:

NTLM. This option is available with the HTTP protocol only. The client is authenticated by using a challenge-response scheme against Windows accounts. NTLM authentication is well suited for a workgroup environment and is more secure than Basic authentication. The service is authenticated by using an SSL certificate.

Here are the security settings for IIS6 and IIS7:

image image

The wsHttpBinding configuration on the client:

  













The client configuration using the wsHttpBinding:

  





Using the dummy certificate will be rejected by WCF with the following error:



Could not establish trust relationship for the SSL/TLS secure channel with authority '10.166.3.2'.


A workaround is to use the RemoteCertificateValidationCallback to validate the certificate explictely as this is done in the following code


:
  

private void Form1_Load(object sender, EventArgs e)
{
System.Net.ServicePointManager.ServerCertificateValidationCallback +=
new System.Net.Security.RemoteCertificateValidationCallback(ValidateCert);
}

This will inform the WCF that there are no errors:

  
private bool ValidateCert(object sender,
X509Certificate cert,
X509Chain chain,
System.Net.Security.SslPolicyErrors error)
{
return true;
}

Then, the AIF WebService is ready to be consumed:

  
private void button1_Click(object sender, EventArgs e)
{

A01ServiceServiceClient proxy = new A01ServiceServiceClient();
proxy.ClientCredentials.Windows.ClientCredential.Domain = "CONTOSO";
proxy.ClientCredentials.Windows.ClientCredential.UserName = "Administrator";
proxy.ClientCredentials.Windows.ClientCredential.Password = "pass@word1";
string message = proxy.HelloWorld("toto");
proxy.Close();
MessageBox.Show(message);
}

23 June 2010

Installing the COM Business Connector (mod 24/06/2010)

The COM Business Connector (COM.BC) is a legacy component from the Axapta (before Dynamics Ax) product that is at his end of lifecycle. Nevertheless is still used by many customers and still supported from Microsoft for Ax4 and Ax2009. In most of the time it is still used in applications that were already running with Axapta3. With the COM.BC and Ax4 and Ax2009 there is no need to change the code that was written for the the COM.BC from Axapta3, but the installation and the setup for the COM.BC changed.  So here is how to install and configure the COM.BC for Ax4 and Ax2009:

The installation process for the COM.BC is described on msdn. This has to be done explicitly outside of the default setup-process in a command-promt with administrator authorizations (run as admin):

D:\Setup.exe HideUI=1 AcceptLicense=1 AcceptLicenseTerms=1  InstallComBusinessConnector=1

(modified the 24/06/2010) : The argument is called AcceptLicenseTerms and not AcceptLicense as descibed on the msdn page. (Thanks Stefan :-) )

As a COM+ component this isn’t registered as a DCOM component during the setup as this was done on Axapta 3. The setup of the COM+ component can be done after the installation with the Component Services administration tool or by scripts (VBScript or Power Shell). The administration tool is described with details on technet.

Here’s a short description on how to configure the COM.BC with the administration tool. Just follow the screenshots:image

image

Choose any meaningful name:

image Configure the proxy-user as the application identity.

imageand then continue without with the defaults to the end of the wizard.image

image

image The AxCOM.dll is installed in the local client directory.

image

image

image

image

Now it comes to the configuration of the security settings of the COM+ application. On msdn the article about Access Checks contains the following very interesting note:

Note  As of Windows Server 2003, access checks are enabled by default when creating a COM+ application. Access checks are enabled by default at the application level and disabled by default at the component level. Previously, access checks were disabled by default at the application level and enabled by default at the component level.

So depending of your operation system you have to deactivate this setting explicitly.

image

This has to be deactivate for asp-applications, because the authentication of asp-application is done on an application level and not by the IIS. The IIS authenticates the user as anonymous and therefore the thread that executes the request will run under the user that is configured as anonymous user. This is by the default the IUSER_Machinename and this user hasn’t the privileges to call a COM+ application.

If you want to activate the access check nevertheless, you need to configure the application user identity as proxy user and not the IUSR. With IIS7 this is done here:

image

With the IIS the proxy user has to be configured manually:

image

Now the role-based security for COM+ can be used. This is not described in this article since this goes far beyond of the subject of this article.

09 February 2010

Services References with Dynamics Ax 2009

WebServices that are not based on the WCF, might implement Xml-schema that are not supported by the WCF. Dynamics Ax 2009 (AOT/References/Service References) is using the "svcutil.exe", which is part of the WCF, for generating the proxies that are communicating with the WebServices.
Dynamics Ax 4 was using the "asmx"-services from the .Net 2 framework, and was offering some functionalities which are not supported with the WCF (as the extensions), you have to create manually the proxies if your WebService requires these kind of elements.
The easiest way is to take the Wsdl-file and create with the wsdl.exe the necessary proxies which you can reference (AOT/References) and then consume the WebService by these custom-proxies.
A complete list of what is supported or not (ignored or forbidden) with the WCF can be found here.