Search This Blog

Showing posts with label AIF. Show all posts
Showing posts with label AIF. Show all posts

26 June 2011

Batchable AxdSend-class in Ax2009 and Ax2012

The AxdSend-class is a very easy to implement class, that helps you writing outbound services for Dynamics Ax 2009 and 2012. The AxdSendExchangeRates-class from Ax 2009 (not existing in Ax 2012 anymore) gives you an idea of how to use this class. Unfortunately there are some reasons why the AxdSend-class cannot run as-is in batches:

  1. The base class: The AxdSend-class needs to derive from RunBaseBatch.
  2. The dialog: The dialog is built on the axdSend-form which does not provide the 'tab'-control for the RunBaseBatch-dialog. This form needs to be modified by adding a new tab-control named 'tab'. Otherwise you would get an exception from the buildControl-method in the DialogForm-class. Btw: The name 'tab' is hardcoded in the tabName-method of the same class.
  3. The method sendMultipleDocuments: calling this method results in calling the run-method, and, as you know, batches are executed by calling the run-method...
Changing this would let the AxdSend-class be 'batchable', but unfortunately the class wouldn't be executable in the interactive mode anymore. This, because the dialog form from the AxdSend, which is opened by calling the prompt-method, requires these members being initialized:
  • aifDocumentClassId
  • serviceClassId
  • aifConstraintList
  • aifSendMode
  • sendActionType
  • aifActionId
My suggestion here is to create a new base-class for batchable AxdSend-classes to isolate these modifications as much as possible. You can download a private project  that contains my modifications/new classes for Ax2009 in all concerned AOT-objects:
  • AxdSend-class
  • axdSend-form
  • AxdBatchableSend-class (custom base-class)
  • AxdSendExchangeRates as an example how to use the AxdBatchableSend class
The batch will use the endpoint that is stored in the usage-data. So the batch needs to be executed at least once in the interactive mode.
Important note:
Importing this project will overwrite these objects and overwrite all modifications in the same layer, too. Please be careful when importing the project.
These modifications are not compatible with Ax2012, but it requires only slight changes to adapt this to Ax2012. I will upload a project for Ax2012 once Ax2012 is released.

Update: (30/06/11) I fixed an issue with the initialization of the endpoint-list.
Update: (02/07/11) Ups, fixed an issue with the dialog initialization.
Update: (04/07/11) Sends only message if query returns more than one element.

19 June 2011

Exporting AIF endpoints with Dynamics Ax 2012

What a good news in Dynamics Ax 2012! The nightmare while deploying AIF endpoints has finally an end and you do obviously not need to be worried about changed classIDs and RefRecIds (AifDataPolicy does reference AifDocumentField by the RecId) anymore. Here's a guide how to export the endpoints by definition groups in Ax 2012 on Msdn.

08 February 2011

Aif changes implicitly document schema when changing underlying table

Changing the mandatory property of fields in tables that are used in Aif-documents does change implicitly the document schema. The table FDI_AifModTest_CF does have the following fields: PK, opt, opt1, mand and mand1. The mandatory fields are flaged aith "m":

Mandatory fields in version 1 and 2

In the beginning the mandatory fields of the table are: PK, mand and mand1.
After having created and configured  the Aif-service, the document schema looks like this:

Document schema according the version 1
 Then, in a second step, the mandatory field is changed as descibed in the first graphic. After refreshing the Aif-services the document schema changed without any notification:

Document schema according the version 2
So this shows that changing the field to mandatory changes the schema, but changing from mandatory to optional does not change the schema. The schema change does make sense but unfortunately this is done completely transparent to the user and there is by default no possibility to get notified by this. So, doing an Aif-service refresh can cause regressions and has to be done with precaution.

15 January 2011

Specific order of fields in Aif messages

Aif-messages require the data to be defined in a specific order. This is why in the schema file, the Aif data-types (declared as complex types) are declared with the xs:sequence indicator:

Example from the DirAddressService:
...

    
      
      
            ...
    
    
    
  
...

This is particularly surprising, as the elements in an entity are always ordered alphabetically... :-\

Aif message header editor (reloaded)

I blogged some weeks ago about my very simple tool to change Aif header-information in Xml-files. (Article deleted)
I reviewed the code and made it now usable "as is". So it is now more then just a proof of concept :-) The project is hosted on CodePlex under the new GNU license (so that you can do whatever you like to do with the code without restrictions).
This tool makes it now possible to modify the content of the Aif-message and to change the file-owner, which is used by Aif to authenticate messages by comparing the file-owner with the source endpoint user.
The tool has a graphical user interface and a simple comand-line interface, so that you can include this tool in scripts which makes it easier to automize creating messages.
The Guid looks like this:
It is very easy to use: just open the valid Xml-file with the "..."-button. If the Xml-files are associated with this tool, a double-click will work, too. Then choose your destination directory. This will be probably the directory that you configured for the incoming messages in Dynamics Ax and choose the same user for the file owner and the "source endpoint user". The Aif authenticates the Aif-user by comparing the "source endpoint user" in the header with the document owner.
A new functionality is the command-line interface:

Type "-help" for a simple "how-to" use this tool and include this in your cmd-script for an automized file-creation...

This tool is provided "as-is", and nobody (including me), will be responsable for any damage this tool might cause... ;-)

Please feel free to report any issues on the project homepage or just drop me a mail.

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}

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

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)..