Tip #416: You have OAuth token, now what?

You went through all the motions of authorization endpoints, return URIs, codes and whatsnot and finally got the magic mushroom authorization token. Now what?

Option 1

Use HttpClient to send requests to the CRM endpoints, add authorization token to the header of every request:

HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = 
   new AuthenticationHeaderValue("Bearer", accessToken);

Once reply is received, go through the pain of manually parsing the return values.

Option 2

Download CSDL file for OrganizationService, manually add a service reference to your project, generate custom organization context, then add some fairy dust:

var service = new CrmOrgContext(new Uri(ODataUrl));
service.SendingRequest2 += (sender, args) => 
   args.RequestMessage.SetHeader("Authorization", 
        "Bearer " + token);

// active accounts
var accounts = service.AccountSet.Where(
   a => a.StateCode.Value == 0);

Better but manual processing will still be required in some cases and we’ll have to refactor all our existing data access code.

Option 3

Spend 10 minutes reading What’s new for developers in CRM 2015, find new namespace Microsoft.Xrm.Sdk.WebServiceClient containing OrganizationWebProxyClient and change your code to:

var orgService = new OrganizationWebProxyClient(
   new Uri(serviceUrl), false)
   {
      HeaderToken = token,
      SdkClientVersion = "7.0"
   };
var userId = ((WhoAmIResponse)orgService.Execute(
   new WhoAmIRequest())).UserId;

These classes support executing message requests through the /web endpoint of the Discovery.svc or Organization.svc when authenticated with OAuth

Now old code works without any changes and authorization is transparent. Which is exactly what we’ve been trying to do all these years.

10 thoughts on “Tip #416: You have OAuth token, now what?

  1. Atul Barve says:

    Hi,

    I did exactly what you said in part3. However I am getting the below error.

    I used https://companyname.crm.dynamics.com as the URL, and the error i get is,
    I have also tried https://companyname.api.crm.dynamics.com/XRMServices/2011/Organization.svc

    “The content type text/html; charset=utf-8 of the response message does not match the content type of the binding (text/xml; charset=utf-8). If using a custom encoder, be sure that the IsContentTypeSupported method is implemented properly. The first 1024 bytes of the response were: …”

    I used straight http requests to generate the OAuth Token from Azure AD as documented on MSDN.

    I am using the CRM 2015 SDK

    Any Ideas?

    Thanks
    Atul

    • Atul,

      looks like you’re getting html back, not xml. That usually happens if response is an error message dressed up as html (e.g. 404). What’s your token looks like and what are the first 1024 bytes of the response? It may shed some light on why you’re getting an error back.

      Cheers
      George

      • Jelle Verdoodt says:

        Hello George,

        Thank you for this code.
        Unfortunately I have the same error as Atul. I generated my token through the Outlook OAuth Sandbox (for testing purposes).

        InnerException: (415) Cannot process the message because the content type ‘text/xml; charset=utf-8’ was not the expected type ‘application/soap+xml; charset=utf-8’.

        I am using a WCF service.

        https://gyazo.com/281c3eac87f5b12e906ecca8fd386752 My token.
        I cut it on the right side since I don’t know which information I can/should show.

        Hopefully you can help me because your solution would be perfect for my situation.

        • Have you granted consent in AAD for your application to access CRM?

          • Jelle Verdoodt says:

            Hello, sorry for the delayed answer and thank you for your responds.

            I have granted consent to my application so that should be good now. I also changed my serviceURL to organization.svc/web which solved the XML error but now I am getting another error:

            “Bearer error=invalid_token, error_description=Error during token validation!”

            The token does seem correct since it comes from the correct application from my AD. Any thoughts?

          • Looks like you are not requesting the right resource. Can you share the line of code obtaining the token?

          • Scott Berry says:

            I hit the same error as Jelle.

            The root cause for me was not appending the following bit: /xrmservices/2011/organization.svc/web

            to the instance Url inside the serviceUri argument.

  2. Santhosh says:

    Hi ,

    how Can i generate access token for Dynamics CRM ??

  3. Alexey Shytikov says:

    Hi,

    Sorry, maybe I’ve missed that, but do you have the article that shows how to get a token? Since I can get comprehensive walk-through for very long time.

    Would really appreciate your help on that one. Many thanks in advance!

    • Hey Alexey,

      there are few samples floating around. For example, we described headless server-to-server authentication not so long ago in tip 767.

      Process of getting the token using client authentication flow is usually more involved (because you need to provide a redirect URL that converts code to token, etc). For active clients, including non .NET, start here. For passive clients, e.g. web sites or custom api, start here.

      If you’re after javascript, SPA sample has what you’re after.

      In short, you’d be using one or another flavor of ADAL to make your life simpler. In the new year I’m planning to put together couple walkthroughs but the above should get you started in the meantime.

      HTH
      George

Leave a Reply

Your email address will not be published. Required fields are marked *