Introduction

The Dynamics GP service based architecture supports two authentication modes: Windows and Azure. The former utilizes a domain controller to authenticate incoming users. The latter is a cloud-based solution where authentication is delegated to Azure Active Directory. In this mode, the authentication service returns tokens to the caller that then get passed around to other services. In this post we will see how to use each mode.

Before we get started, it’s worth mentioning that the service based architecture builds on the new authentication/identity features that are now part of Dynamics GP. Authentication must already be configured and users must mapped before service requests will succeed.

 

Windows Authentication

Making a request with Windows authentication is very straightforward. Credentials are passed to the service in one of two supported ways: NTLM or basic.

NTLM

NTLM authentication shines in situations where the caller and service are on the same domain. If you have ever hit a service based architecture endpoint from a browser and it “just worked” with no prompting, this is NTLM at work. When this happens, the browser is authenticating automatically with the credentials of the logged-on user. A similar thing can be done from code by asking the HTTP library in question to use the default credentials. One way to do this in C# using the HttpClient class is by configuring the handler in this way:

var httpClient = new HttpClient(new HttpClientHandler() 
{
    UseDefaultCredentials = true
});

Using NTLM does not mean you must use the logged-in user’s credentials. The HttpClient class can be told to use alternate credentials by using the Credentials property on the HttpClientHandler instance. There are examples of this online.

In addition, most tools like Postman default to NTLM unless another authentication mode is specified. Here is an example where I simply opened the tool and pasted in a URL. Since I specified no authentication options, it defaulted to NTLM with my current credentials:

Basic

Another way to use Windows authentication is by passing credentials explicitly in the header of the HTTP request. This is commonly referred to as basic authentication. In this mode, the credentials are sent in a base64-encoded string (in other words, in the clear) in the Authorization header of each request. For this reason, basic authentication should never be used with a non-HTTPS endpoint! The GP service requires SSL for all requests, meaning all communication between the client and server is encrypted (credentials included). An example of using basic authentication in C# using the HttpClient class is like this:

string raw = String.Format("{0}:{1}", user, password);
byte[] bytes = Encoding.ASCII.GetBytes(raw);
string base64Creds = Convert.ToBase64String(bytes)

var client = new HttpClient(); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", base64Creds);

Once configured in this way, the client instance will append the authentication header to every request it makes.

The Postman tool also understands how to use the basic authentication mode as the screenshot below indicates. Being able to easily set the credentials of a request is very useful when testing scenarios that request different user credentials during development.

Azure Authentication

Authenticating with Azure Active Directory is quite different from the approaches above. In this mode, the client makes a request to an Azure service asking for an access token for a particular resource. The service requests credentials, validates them, checks the user’s access to the resource, and then serves back a token. The client can now include the signed token in its Authorization header when calling the service based architecture endpoint.

For information about configuring Dynamics GP for Azure Active Directory, refer to the published install/admin documentation for the web components. The web client must be able to successfully log in using Azure credentials for service calls to have any chance of success.

For information about using Azure authentication in a client application, check out the published samples like this one. Some of the particulars will vary depending on the technology used, but the concepts have universal relevance. The necessary setup steps for a client application involve:

  • Creating an Azure Active Directory application for the client application

  • Granting access from the client to the service application

  • Including the relevant IDs and URIs in the client application

The recommended course of action is to first work through a generic Azure AD sample, then apply those concepts to an application using the service based architecture.

Below is my incredibly simple adaptation of the concepts from the samples to a console application. My app simply calls out to the Azure endpoint to retrieve a token, then writes the token to the console. A real application would then use this token to make service calls and would also properly handle things like caching & refreshing it.

using System;
    using Microsoft.IdentityModel.Clients.ActiveDirectory;

    internal class Program
    {
        private static void Main(string[] args)
        {
            string tenant = "[YOUR TENANT DOMAIN]";
            string authority = "https://login.microsoftonline.com/" + tenant;
            string clientId = "[YOUR CLIENT ID GUID]";
            string appResourceId = "[YOUR AZURE RESOURCE ID]";
            Uri redirectUri = new Uri([YOUR REDIRECT URI]);

var authContext = new AuthenticationContext(authority, new FileCache()); AuthenticationResult authResult = null;
authResult = authContext.AcquireToken(appResourceId, clientId, redirectUri);
Console.WriteLine("NAME : {0}", authResult.UserInfo.DisplayableId); Console.WriteLine("ID : {0}", authResult.UserInfo.UniqueId); Console.WriteLine("TOKEN : {0}", authResult.AccessToken); } }


When I run this, I get output like the following:

NAME  : chris@[MY TENANT DOMAIN]
ID    : [MY USER GUID]
TOKEN : eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1uQ19WWmNBVGZNNXBPWWlKSE1i
YTlnb0VLWSIsImtpZCI6Ik1uQ19WWmNBVGZNNXBPWWlKSE1iYTlnb0VLWSJ9.eyJhdWQiOiJodHRwczo
...
[REST OF MY TOKEN STRING]


I can then take the token string and put it into an authorization header of a HTTP request. I can even do this using tools like Postman by adding an authorization header of the form bearer [TOKEN STRING].

It is worth noting that Azure Active Directory does much more than what we have described here. To dig deeper into advanced features and configurations, see the published samples and documentation provided by that team.

Conclusion

The authentication story in the Dynamics GP Web Client has been evolving. The Service Based Architecture feature plugs into that infrastructure to simplify matters when using both the client and integrating applications.