Search This Blog

Showing posts with label architecture. Show all posts
Showing posts with label architecture. Show all posts

12 July 2011

Windows EventLogs with X++

Here's a very small and simple class that makes it very easy to use the Windows EventLogs with X++. It creates, if necessary, a new log/source and logs the events there:
Just derive from the abstract base-class "WinEventLogsBase" (as it is done in WinEventLogs_Batches) and overwrite the log/source and messageId, so that your events are unique.


The job TestEventLogs is an example how to write EventLogs:
static void TestEventLogs(Args _args)
{
    WinEventLogsBase logs;
    System.Diagnostics.EventLogEntryType type = System.Diagnostics.EventLogEntryType::Error;
    System.Int32 eventId = 110;
;
    //Works well, but in the EventLog for Workflow events
    SysWorkflowHelper::writeEventLogEntry("Test simple error from Workflow.");

    //uses the EventSource for the Dynamics Server with the instance suffix to write a message
    System.Diagnostics.EventLog::WriteEntry("Dynamics Server 01", "Test simple error with WriteEntry.");
    //will result in:
    //The description for Event ID ( 0 ) in Source ( Dynamics Server 01 ) cannot be found.
    //because this source is linked to the ressource:
    //C:\Program Files\Microsoft Dynamics AX\50\Server\DynamicsAx1\Bin\Ax32Serv.exe
    //in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application\Dynamics Server 01
    //which doesn't know how to handle that EventId

    //now by selecting the Dynamics Ax standard EventId 110:
    System.Diagnostics.EventLog::WriteEntry("Dynamics Server 01", "Test simple error with WriteEntry.", type, eventId);
    //Works pretty fine, but: always the same EventSource and EventId, which is not possible to track for many
    //monitoring tools like for example Heroix Longitude which do only interpret the EventId.

    //now that little tool:
    logs = new WinEventLogs_Batches(); //specialization for logs

    //WinEventLogs_Batches uses an EventSource and EventLog on its own
    logs.writeError("Test simple error");  //uses a default EventId
    logs.writeInfo("Test simple info", 4711); //uses an explicit EventId
    logs.writeWarning("Test simple warning");

    logs = new WinEventLogs_Test(); //specialization that uses the Eventlog "Application" for the source

    //WinEventLogs_Test uses its own EventSource but "Application" as EventLog
    logs.writeError("Test simple error");
    logs.writeInfo("Test simple info", 4712);
    logs.writeWarning("Test simple warning");
    //because this tool links the registered EventSource to:
    //c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\EventLogMessages.dll
    //it is now possible to use any custom EventId which is not predifined in the resource like in the
    //first example.
}

10 July 2011

Authenticating a user with user-name and password against Windows with X++

The AccountManagement Namespace was introduced with .Net 3.5 and provides some very useful classes which are, by referencing this assembly, available with X++, as well. At least if you've installed .Net 3.5.

Here's an example how to authenticate a username and password against Windows with the PrincipalContext class and the ValidateCredentials-method.
boolean isAuthenticated = false;
System.DirectoryServices.AccountManagement.PrincipalContext principalContext;
;

principalContext = new System.DirectoryServices.AccountManagement.PrincipalContext(System.DirectoryServices.AccountManagement.ContextType::Domain, "contoso.com");
isAuthenticated = principalContext.ValidateCredentials("username", "password");
principalContext.Dispose();

if (isAuthenticated)
{
    //do something
}
else
{
    //do something
}

Update: (15/07/11) And bcause of the Google search keywords: The username and password for the contoso.com VPC are Administrator and Passw0rd (or pass@word1 depends on the vpc) ... ;-)

09 July 2011

Authentication of the different components in Ax 2009

One of the most annoying subjects in Ax2009 is installing and configuring the huge number of components which do need to authenticate each other. There are Reporting Services, Analysis Services, SharePoint Services (or MOSS) on IIS, AIF MSMQ, AIF WebServices, AIF BTS, the Ax AOS,  Internet Explorer, SMB for the application file-share and the Ax client (some do have BC.Net applications as well). If they are all installed on one box, this is quite easy to maintain. But a distributed installation (especially on a large scale) is extremely complicated and requires a profound understanding of Kerberos authentication.  Because I recently had to find an issue on my erroneous installation, here's a nice schema of my current Ax 2009 configuration which might help you as well:


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