Skip to main content

Notifications

Announcements

No record found.

Dynamics 365 general forum

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,329 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

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

November Spotlight Star - Khushbu Rajvi

Congratulations to a top community star!

Forum Structure Changes Coming on 11/8!

In our never-ending quest to help the Dynamics 365 Community members get answers faster …

Dynamics 365 Community Platform update – Oct 28

Welcome to the next edition of the Community Platform Update. This is a status …

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 291,269 Super User 2024 Season 2

#2
Martin Dráb Profile Picture

Martin Dráb 230,198 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156

Leaderboard

Featured topics

Product updates

Dynamics 365 release plans