Wednesday 2 August 2017

Get access token to expose data outside of D365 for Operations

You might be aware that Dynamics 365 follows Azure active directory(AAD) authentication to validate the legitimate users.

I am not gonna explain you the full authentication scenario here. It's already explained on below link
D365 for operation Authentication

I assume that you have successfully registered Native App on your Azure subscription.
your redirectURI will look something like this(change the URI with actual)
https://<EnvironmentName>devaos.cloudax.dynamics.com/
Tip: Take utmost care of character casing while defining RedirectURI

 Now, I will show you the code snippet to get access token and how to use it to expose data outside of D365 for Operations.

 I am using Visual studio 2015 for this purpose.

1. Create new C# project in VS as GetAccessTokenD365.
2. Add Microsoft Identity model package(Microsoft.IdentityModel) from Nuget if not available for reference already.
3. Then add class to your project name it as ClientConfiguration. Here you will define parameters to be used for authentication as below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GetAccessTokenD365
{
    public partial class ClientConfiguration
    {
        public static ClientConfiguration Default { get { return ClientConfiguration.OneBox; } }
 
        public static ClientConfiguration OneBox = new ClientConfiguration()
        {
            UriString = "https://*******devaos.cloudax.dynamics.com/",
            UserName = "axuser@TenantId.onmicrosoft.com",
            Password = "password",
            ActiveDirectoryResource = "https://******devaos.cloudax.dynamics.com",

            ActiveDirectoryTenant = "https://login.windows.net/tenantId.onmicrosoft.com", 
            ActiveDirectoryClientAppId = "ActualClientId",
        };
 
         public string UriString { get; set; }
         public string UserName { get; set; }
         public string Password { get; set; }
         public string ActiveDirectoryResource { get; set; }
         public String ActiveDirectoryTenant { get; set; }
         public String ActiveDirectoryClientAppId { get; set; }
}
}

4. Add another class and name it as OAuthHelper. This class contains whole logic to deal with AAD Authentication.
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GetAccessTokenD365
{
    public class OAuthHelper
    {
          /// 
         /// The header to use for OAuth.
         /// 
         public const string OAuthHeader = "Authorization";

        /// 
        /// Retrieves an authentication header from the service.
        /// 
        /// The authentication header for the Web API call.
        public static string GetAuthenticationHeader()
        {         

            string aadTenant = ClientConfiguration.Default.ActiveDirectoryTenant;
            string aadClientAppId = ClientConfiguration.Default.ActiveDirectoryClientAppId;
            string aadResource = ClientConfiguration.Default.ActiveDirectoryResource;

            AuthenticationContext authenticationContext = new AuthenticationContext(aadTenant);
           
            // OAuth through username and password.
            string username = ClientConfiguration.Default.UserName;
            string password = ClientConfiguration.Default.Password;        

            // Get token object
            AuthenticationResult authenticationResult = authenticationContext.AcquireToken(aadResource, aadClientAppId, new UserCredential(username, password));

            Console.WriteLine(authenticationResult.CreateAuthorizationHeader());
            Console.ReadLine();

            // Create and get JWT token
            return authenticationResult.CreateAuthorizationHeader();
        }       
    }
}

5. Now, write a class with a main method to execute the logic.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GetAccessTokenD365
{
    class Program
    {
        static void Main(string[] args)
        {
            OAuthHelper OAuthhelper;

            OAuthhelper = new OAuthHelper();
            OAuthHelper.GetAuthenticationHeader();
        }
    }
}


6. We are done with the code. Finally, your solution explorer will look as shown above.
Now its the time to execute it and get access token. Just build the project and run it.
Now we have access token with us, its time to test it. I am using Postman tool for this purpose, you can use fiddler as well.
Copy the generated token from console.

Open Postman and type the URL(public data entity) to get all customers which will look like as below.
https://*******devaos.cloudax.dynamics.com/data/Customers

As shown in the above picture, paste your token alongwith keyword 'bearer' in to the value field for Authorization key.
And then click on Send button, it will produce the resulting JSon in body of Postman as shown below.


Hurray! We are done. And I am done with my 1st technical post.
I welcome any suggestion or question.

4 comments:

  1. I have tried to use your demo code to get access the auth token from my azure d365 but keep on getting the following exception:
    The request body must contain the following parameter: 'client_secret or client_assertion'

    ReplyDelete
    Replies
    1. I am sorry for late reply...There must be something wrong with the client App in your case..please verify it from https://community.dynamics.com/ax/b/axsupport/archive/2017/07/13/recurring-integrations-in-dynamics-365-for-operations

      I have tested this on Update 7, it might require something additional for later versions..

      Delete
  2. Does it only work if you are working in the cloud environment? I think most of people working locally with VM because it costs fortune to develop in the azure environment.

    ReplyDelete
    Replies
    1. Yes..It has been created and tested for cloud environments only....

      Delete