Skip to main content

Notifications

Announcements

No record found.

Dynamics 365 general forum
Unanswered

Dynamics 365 OAuth For WebAPI

Posted on by Microsoft Employee

Hi all, I'm having trouble using the access token to access Dynamics WebAPIs such as using an endpoint to create an Account or Incident entity. I have tried both v1 and v2 version of OAuth and have tried setting various permission in the app registration and playing around with different scope parameter values in my request but to no avail. Any help would be greatly appreciated.

I have already registered an Web/API application in the Azure portal and have subsequently followed the instructions found in Microsoft identity platform and OAuth 2.0 authorization code flow to generate an Access Token.

Here's my Http request to get the initial auth code:

String authUrl = https://login.microsoftonline.com/common/oauth2/v2.0/authorize
authUrl = RequestUtil.addQueryParameter(authUrl, "client_id", DYNAMICS_CLIENT_ID.get());
authUrl = RequestUtil.addQueryParameter(authUrl, "redirect_uri", localhost/.../dynamicsoauthcallback);  
authUrl = RequestUtil.addQueryParameter(authUrl, "scope", "openid offline_access https://admin.services.crm.dynamics.com/user_impersonation");

//have also tried setting https://yexttest.api.crm.dynamics.com/ as the "resource" parameter value in V1 of OAuth
authUrl = RequestUtil.addQueryParameter(authUrl, "state", "12345");
authUrl = RequestUtil.addQueryParameter(authUrl, "response_type", "code");
authUrl = RequestUtil.addQueryParameter(authUrl, "response_mode", "query");

Here's my followup call using the returned auth code to get an AccessToken:

String response = RequestBuilder.forUrl(exchangeTokenUrl)

.addHeader("Content-Type", "application/x-www-form-urlencoded")
.addPostParam("client_id", app.clientId())
.addPostParam("client_secret", app.clientSecret())
.addPostParam("grant_type", "authorization_code") 
.addPostParam("redirect_uri", app.redirectUrl())
.addPostParam("scope", "openid offline_access admin.services.crm.dynamics.com/user_impersonation")
// also tried for V1 .addPostParam("resource", "yexttest.api.crm.dynamics.com/.../v9.1")
.addPostParam("code", authCode)
.stringPostRequest();

The response I received is valid and I can successfully obtain both the access token and the refresh token. 

Now here's the issue, I'm unable to use the Access Token to make any calls to the Dynamics CRM:

Example: 

GET /api/data/v9.1/incidents? HTTP/1.1
Host: yexttest.api.crm.dynamics.com
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJub25jZSI6IkFRQUJBQUFBQUFEQ29NcGpK....
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0

=========================================================

Response: 

HTTP Error 401 - Unauthorized: Access is denied

Looking closely at the response Headers, this is what I noticed: WWW-Authenticate →Bearer error=invalid_token, error_description=Error during token validation!, authorization_uri=login.microsoftonline.com/.../authorize, resource_id=yexttest.api.crm.dynamics.com

Can someone please explain why my validation is failing? Am I using the correct OAuth flow for authentication (I read online somewhere that doing the client credentials grant flow worked for some people)? Are there any special configurations I need to set up for my Dynamics Instance at https://yexttest.api.crm.dynamics.com/?

Thank you very much!!!

  • KiranV Profile Picture
    KiranV 10 on at
    RE: Dynamics 365 OAuth For WebAPI

    Change the scope to this format:

    https://{organization}.crm.dynamics.com//user_impersonation (must have double slash)

    I am able to access D365 API using the MSAL JS library with above scope format. 

  • Community Member Profile Picture
    Community Member Microsoft Employee on at
    RE: Dynamics 365 OAuth For WebAPI

    Hi Leo, 

    Thank you for your response, but my trouble is not in requesting my token because I can get a successful response. Here's what my sample get token response looks like:

    {

    "token_type": "Bearer",

    "scope": "[View:https://admin.services.crm.dynamics.com/user_impersonation:750:50]",

    "expires_in": 3600,

    "ext_expires_in": 3600,

    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6I....",

    "refresh_token": "OAQABAAAAAADCoMpjJXrxTq9VG9te-7FXij0i6mtg8Vhxd...",

    "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik4tbEMwbi05REFMcXdodUhZbkhRNjNHZUNYYyJ..."

    }

    I have also set oauth2AllowImplicitFlow to true in the app manifest but I'm still getting the 401. 

    When I use the returned access_token to make a get accounts call for the CRM URL under my OAuthed account I get that 401 error.

    What's strange is that I'm using all V2.0 endpoints using "scope" instead of "resource" as opposed to V1.0, but the returned access token's version is still ver 1.0 after I decode the access_token via jwt.ms. Is this a bug on Microsoft's end?

    {

     "typ": "JWT",

     "alg": "RS256",

     "x5t": "N-lC0n-9DALqwhuHYnHQ63GeCXc",

     "kid": "N-lC0n-9DALqwhuHYnHQ63GeCXc"

    }.{

     "aud": "**************************************",

     "iss": "**************************************",

     "iat": 1555511420,

     "nbf": 1555511420,

     "exp": 1555515320,

     "acr": "1",

     "aio": "**************************************",

     "amr": [

       "pwd"

     ],

     "appid": "**************************************",

     "appidacr": "1",

     "family_name": "**************************************",

     "given_name": "Kevin",

     "ipaddr": "**************************************",

     "name": "**************************************",

     "oid": "**************************************9",

     "puid": "**************************************",

     "scp": "user_impersonation",

     "sub": "**************************************",

     "tid": "**************************************",

     "unique_name": "kzhao@yext.com",

     "upn": "kzhao@yext.com",

     "uti": "Vu12e0Cok0K2eYZKuWq0AA",

     "ver": "1.0",

     "wids": [

       "44367163-eba1-44c3-98af-f5787879f96a"

     ]

    }.[Signature]

  • LeoAlt Profile Picture
    LeoAlt 16,327 on at
    RE: Dynamics 365 OAuth For WebAPI

    Hi partner,

    It looks that you met trouble when requesting for token.

    You could go to Azure portal, open the application you've created and  change "oauth2AllowImplicitFlow" to True.

    community354.png

    I've tried to request token in Postman and it worked well and I could call web api successfully.

    community354.png

    I suggest that you could set an environment of Dynamics 365 in postman and get the token, and then test if this token woked, if everything is ok ,then you could use this token in you code.

    How to set environment in Postman

    https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/webapi/setup-postman-environment

    You could also refer to the following posts about this issue.

    https://stackoverflow.com/questions/37215742/401-unauthorized-authentication-using-rest-api-dynamics-crm-with-azure-ad

    https://community.dynamics.com/crm/f/117/t/193506?pi61802=2#responses

    By the way, please hide your Organization url to protect your privacy and data security.

    Hope it helps.

    Best Regards,

    Leo

Helpful resources

Quick Links

Replay now available! Dynamics 365 Community Call (CRM Edition)

Catch up on the first D365 Community Call held on 7/10

Community Spotlight of the Month

Kudos to Saurav Dhyani!

Congratulations to the June Top 10 community leaders!

These stars go above and beyond . . .

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 287,696 Super User

#2
Martin Dráb Profile Picture

Martin Dráb 225,490 Super User

#3
nmaenpaa Profile Picture

nmaenpaa 101,148

Leaderboard

Featured topics

Product updates

Dynamics 365 release plans