Connect to Dynamics 365 Web API using OAuth 2.0 – Authorization Code Grant Type

In the previous post we covered Password and Client Credentials grant type, here we’d be looking at the Authorization Code Grant Type.

The Authorization Code Grant Type is for the Confidential Clients i.e. basically for the server side web applications that are written in server side language and source code is not available to the public. So these application can use client secret when requesting token with authorization server. We can also have Single-Page Apps, who have their entire source available to the browser, and that cannot maintain the confidentiality of the Client Secret, use the same flow for getting the authorization code and in the step when requesting for access token pass only the client id and authorization code without using client secret.

In Authorization Code Grant Flow

  • The client application redirect the user agent to the Azure AD Authorization Endpoint.

Mainly it passes below values to the

response_type code
client_id Application Id
redirect_uri Redirect URI specified.

To

  • The user authenticates and consents the client application

  • The Azure AD authorization endpoint redirects the user agent back to client application with an authorization code at the redirect URL (i.e. code query parameter)

  • The client application uses this authorization code to request the access token from the authentication token endpoint by passing resource, client_id, grant_type = “authorization_code”, code and redirect_uri as shown below.

  • The Azure AD issues the access token, which the client application can use to call the Web API.

For our sample code to work: –

First Register the Application with Azure Active Directory to get the ClientId.

Get the authorization and token end point. Navigate to Overview and click on Endpoint to get these endpoints.

Also specify a Redirect URI for the application.

Navigate to Authentication and select the suggested Redirect URI.


Below is the sample C# Code: –


static void Main(string[] args)
{
// Dynamics CRM Online Instance URL
string resource = "https://bankfabdemo.crm.dynamics.com";

// application id
var clientId = "eb17e844-adfc-4757-ba6d-5384108e184a";

// redirect URL
var redirectURI = "https://login.microsoftonline.com/common/oauth2/nativeclient";

// Authenticate the registered application with Azure Active Directory.
AuthenticationContext authContext =
new AuthenticationContext("https://login.microsoftonline.com/bd88124a-ddca-4a9e-bd25-f11bdefb3f18/");

AuthenticationResult authResult = authContext.AcquireToken(resource, clientId, new Uri(redirectURI));
var accessToken = authResult.AccessToken;

// use HttpClient to call the Web API
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0");
httpClient.DefaultRequestHeaders.Add("OData-Version", "4.0");
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);

httpClient.BaseAddress = new Uri("https://bankfabdemo.crm.dynamics.com/api/data/v9.0/");

var response = httpClient.GetAsync("WhoAmI").Result;
if (response.IsSuccessStatusCode)
{
var userDetails = response.Content.ReadAsStringAsync().Result;
}

}

Within Postman :

Click on Request Token, login and give consent à

The token à

Hope it helps..

Advertisements

Connect to Dynamics 365 Web API using OAuth 2.0 – Client Credentials

In the last post we learned about connecting to Dynamics 365 Web API using Resource Owner Password Credential (ROPC), here we’d be covering the Client Credentials grant.

Client Credentials grant is designed for the client applications who are the resource owner and when basically there are no users involved, a batch (cron) job or a service using Web API, running in the background, on the server is one such example.

Here we will not be using the authorization endpoint, and the client application will be sending its own credential, instead of impersonating a user, directly to the token endpoint. The benefit compared to basic authentication or API keys is that credentials are not being sent with every request, it is only sent while requesting the access tokens along with all the other benefits of using access token – stateless, fine-grained access control, access token lifetime etc.

Let us see an example of using the Client Credentials grant in our console application. Along with the Client Id that we got when we registered our client application in the Azure Active Directory, we would need the Client Secret.

Follow the below steps to generate the Client Secret

Login to Azure Admin Portal

https://portal.azure.com

Select the application registered and click on Certificates & secrets option


Click on New client secret button to generate the client secret. Copy the generated client secret. Select the expiry as per the need.

Copy the secret generated and save it, as it won’t be available later when we are navigating here.

Also, we can get the Authentication Token Endpoint, for that navigate to Overview à Endpoints

And copy the OAuth 2.0 token endpoint.

Next step is to create the Application User within Dynamics 365 CE corresponding to the client application.

Login to Dynamics 365 CE, Settings à Security à Users àset View as Application Users and click on New button

Set Application Id as the Client Id of the Application registered and specify other mandatory values and save the record.

Assign appropriate security role to the new application user added.

Sample C# Code à


static void Main(string[] args)
{
// Dynamics CRM Online Instance URL
string resource = "https://bankfabdemo.crm.dynamics.com";

// client id and client secret of the application
ClientCredential clientCrendential = new ClientCredential("eb17e844-adfc-4757-ba6d-5384108e184a",
"p.eS+MI9cXkO_gQ02_lMlUXVSVCujyU0");

// Authenticate the registered application with Azure Active Directory.
AuthenticationContext authContext =
new AuthenticationContext("https://login.microsoftonline.com/bd88124a-ddca-4a9e-bd25-f11bdefb3f18/oauth2/v2.0/token");

AuthenticationResult authResult = authContext.AcquireToken(resource, clientCrendential);
var accessToken = authResult.AccessToken;

// use HttpClient to call the Web API
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0");
httpClient.DefaultRequestHeaders.Add("OData-Version", "4.0");
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);

httpClient.BaseAddress = new Uri("https://bankfabdemo.crm.dynamics.com/api/data/v9.0/");

var response = httpClient.GetAsync("WhoAmI").Result;
if (response.IsSuccessStatusCode)
{
var userDetails = response.Content.ReadAsStringAsync().Result;
}

}

Within Fiddler à

Within Postman à

Hope it helps..


Connect to Dynamics 365 Web API using OAuth 2.0 – Resource Owner Password Credential (ROPC)

The ROPC grant type should only be used in scenario when the Client application is absolutely trusted with user credentials and when redirect based flow are not possible. It was introduced for the Legacy Application for quick migration and is now more or less considered obsolete by OAuth Working group, and ideally should not be used.

In this flow, User enters his credentials (username and password) in the client application, when is then sent to Token Endpoint of the Authorization Server for Access Token request. The client application then gets the access token and call/request the protected resources (Web API) and get response. Here we remove the user from the authorization process and are not using the Authorization endpoint at all. The apps using this flow will lose the benefits of multi-factor authentication MFA and Single Sign-On.

Request à

client_id Client id of the app registered in Azure Active Directory.

We can also use the default client id –

2ad88395-b77d-4561-9441-d0e40824f9bc” –

which is setup against Dynamics 365 Online instances.

https://www.crmviking.com/2017/08/piggybacking-on-msdyn365.html

username User’s username
password User’s password
grant_type password
resource Dynamics 365 URL

Sample C# Code à

Create the console application and add the following Nuget Package

https://docs.microsoft.com/en-in/azure/active-directory/develop/active-directory-authentication-libraries


static void Main(string[] args)
{
// Dynamics CRM Online Instance URL
string resource = "https://bankfabdemo.crm.dynamics.com";

// ID of the Application Registered
// "2ad88395-b77d-4561-9441-d0e40824f9bc" - Default Client Id which is setup against Dynamics 365 Online instances.
string clientId = "2ad88395-b77d-4561-9441-d0e40824f9bc";

// username and password of the user
UserCredential userCrendential = new UserCredential("nishantrana@bankfabdemo.onmicrosoft.com", "*******");

// Authenticate the registered application with Azure Active Directory.
// Token URL - https://login.microsoftonline.com/common/oauth2/token

AuthenticationContext authContext =
new AuthenticationContext("https://login.windows.net/common");

AuthenticationResult authResult = authContext.AcquireToken(resource, clientId, userCrendential);
var accessToken = authResult.AccessToken;

// use HttpClient to call the Web API
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0");
httpClient.DefaultRequestHeaders.Add("OData-Version", "4.0");
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);

httpClient.BaseAddress = new Uri("https://bankfabdemo.crm.dynamics.com/api/data/v9.0/");

var response = httpClient.GetAsync("WhoAmI").Result;
if (response.IsSuccessStatusCode)
{
var userDetails = response.Content.ReadAsStringAsync().Result;
}

}

The result: –

Inside Fiddler à

Hope it helps..