Search This Blog

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.