Generating OAuth2 V2.0 Endpoint Tokens for Dynamics 365 / the Common Data Service
OAuth 2.0 authentication can transform into a very deep rabbit hole if you find yourself stumbling into it for the first time. Perhaps this is for a good reason. As the primary authentication mechanism for the vast majority of cloud services available today, there is an obvious expectation that the security aspects of this protocol remain top-notch at all times. Otherwise, all manner of insidious and treacherous individuals could end up poking around into systems that they have no right to be within. To ensure things remain as secure as possible, there is, therefore, a natural expectation that the setup aspects for legitimate access into systems leveraging OAuth2 be not necessarily a cakewalk.
Because OAuth2 is the backbone of Azure Active Directory, which is used to handle authentication into Dynamics 365 online / the Common Data Service, developers will have to cross the Rubicon with OAuth 2.0 at some stage. This action will become even more necessary if you are developing solutions that require a non-interactive login mechanism into the system. Traditionally, developers would have constructed a request similar to the below to generate an access token, which acts as the “key” into your particular service of choice; in this case, a Dynamics 365 online instance:
Request
POST https://login.microsoftonline.com/f38b4010-a9e0-40a8-af5e-626cfb3d85be/oauth2/token HTTP/1.1 --Headers removed for brevity grant_type=client_credentials &client_id=a05645a6-aa66-4441-b243-525563c1df2d &client_secret=myclientsecret &resource=https%3A%2F%2Fmycrminstance.crm11.dynamics.com%2F
Response
HTTP/1.1 200 OK
--Headers removed for brevity
{
"token_type":"Bearer",
"expires_in":"3599",
"ext_expires_in":"3599",
"expires_on":"1588493859",
"not_before":"1588489959",
"resource":"https://mycrminstance.crm11.dynamics.com/",
"access_token":"myaccesstoken"
}
With our “key” in hand, we can then walk up and open the door into Dynamics 365 using a request similar to the below, to return details of the user making the request. The key portion here is the Authorization header value, which must contain the access_token generated in the previous step and be in the format Bearer <Access Token>:
Request
GET https://mycrminstance.crm11.dynamics.com/api/data/v9.1/WhoAmI HTTP/1.1 Authorization: Bearer myaccesstoken --Other headers removed for brevity
Response
HTTP/1.1 200 OK
--Headers removed for brevity
{
"@odata.context":"https://mycrminstance.crm11.dynamics.com/api/data/v9.1/$metadata#Microsoft.Dynamics.CRM.WhoAmIResponse",
"BusinessUnitId":"9941c9c6-f71e-ea11-a812-00224801bc51",
"UserId":"395439d2-d98a-ea11-a811-000d3a7fedbe",
"OrganizationId":"4827d81f-172e-4d9d-b9b2-6db4e7c12490"
}
This request all works fine and dandy, as you can see. The main issue with it though is that, currently, it is utilising version 1 of the OData v2.0 token endpoint that Microsoft expose out to developers for use. This issue is not so much of a problem as things stand today and as noted by this convenient comparison post on the subject – indeed, depending on your scenario, it may be impossible for you to migrate currently, as the version 2 endpoints are missing some features. However, I would argue that the writing is on the wall and that the eventual deprecation of this endpoint is more than likely. For new projects, if you can get away with using V2 of the new endpoint to meet your requirements, you should use this wherever possible.
With all this laid out, we now get to the crux of the matter, which relates to a recent challenge I had – how to get web requests targeting Dynamics 365 moved across to start using the new v2 endpoints? Unfortunately, simply changing the URL to https://login.microsoftonline.com/f38b4010-a9e0-40a8-af5e-626cfb3d85be/oauth2/v2.0/token comes back with the following error:
{
"error":"invalid_request",
"error_description":"AADSTS901002: The 'resource' request parameter is not supported.\r\nTrace ID: 506b590a-7c90-4638-8a39-ff35cd9d1800\r\nCorrelation ID: 1eb1b320-7802-4983-a46d-e6d20c6ede5e\r\nTimestamp: 2020-05-03 07:38:44Z",
"error_codes":[
901002
],
"timestamp":"2020-05-03 07:38:44Z",
"trace_id":"506b590a-7c90-4638-8a39-ff35cd9d1800",
"correlation_id":"1eb1b320-7802-4983-a46d-e6d20c6ede5e"
}
Obliging the error message, by removing the resource key/value pair from our body request, doesn’t give us much joy as well, as we get a new error instead:
“error_description”: “AADSTS90014: The required field ‘scope’ is missing from the credential. Ensure that you have all the necessary parameters for the login request.\r\nTrace ID: afeacc53-92b2-430b-a8a3-bf69af5b1800\r\nCorrelation ID: a6b2a96d-d7d6-4929-8402-5a9da9a27335\r\nTimestamp: 2020-05-03 07:42:54Z”
POST https://login.microsoftonline.com/f38b4010-a9e0-40a8-af5e-626cfb3d85be/oauth2/v2.0/token HTTP/1.1 --Headers removed for brevity grant_type=client_credentials &client_id=a05645a6-aa66-4441-b243-525563c1df2d &client_secret=myclientsecret &scope=https%3A%2F%2Fmycrminstance.crm11.dynamics.com%2F.default



Like
Report
*This post is locked for comments