Tip #767: Server-to-server authentication is here

HeadlessWoot, woot! At long last we can create passive clients – the ones that do not have someone sitting in front of them. Clients like web sites or services – and authenticate them without using username and password AND get the magic bearer token that is good to use in Web API.

The detailed walkthrough is available, describing in glorious details the process of creating a web site (MVC applicaton) that can talk to Dynamics CRM. Don’t be put off by references to the web sites – you don’t have to be building one to take advantage of the feature. In fact, substantially lesser efforts required to create an equivalent console application that can be deployed as a Web Job and run unattended as a service.

  1. Register your application on Azure AD. No need for multi-tenant, single-tenant will do. What I found is that if you are using https://portal.azure.com, it does not create the application instance locally requiring the logon and consent. Easy to say with the web site, not so much with a console application. If instance is not created you will not be able to create an application user (see below). There is probably another way to do it but using old portal does immediately create an instance.
    Local Azure app
  2. Add permissions to access CRM and generate your key (same instructions)
  3. Create an application user. This is where the good stuff happens, we’re allowing a specific application to access CRM without a consent from a user.
  4. Create console application in Visual Studio and add nuget packages
  5. You are good to go!
  6. The code looks like this:
static void Main(string[] args)
    string organizationUrl = "https://notarealone.crm.dynamics.com";
    string clientId = "6db9cae3-dead-beef-dead-7179d4958975";
    string appKey = "get you own";
    string aadInstance = "https://login.microsoftonline.com/";
    string tenantID = "your tenant id";

    ClientCredential clientcred = new ClientCredential(clientId, appKey);
    AuthenticationContext authenticationContext = new AuthenticationContext(aadInstance + tenantID);
    AuthenticationResult authenticationResult = authenticationContext.AcquireToken(organizationUrl, clientcred);
    var requestedToken = authenticationResult.AccessToken;
    using (var sdkService = new OrganizationWebProxyClient(GetServiceUrl(organizationUrl), false))
        sdkService.HeaderToken = requestedToken;

        OrganizationRequest request = new OrganizationRequest()
            RequestName = "WhoAmI"

        WhoAmIResponse response = sdkService.Execute(new WhoAmIRequest()) as WhoAmIResponse;
static private Uri GetServiceUrl(string organizationUrl)
    return new Uri(organizationUrl + @"/xrmservices/2011/organization.svc/web?SdkClientVersion=8.2");

Last but not least, to quickly find your tenant id, select application in either Azure portal and ask for Endpoints, your tenant id will be splattered all over endpoint urls as a guid that follows the domain.

Tweet about this on TwitterShare on Facebook7Share on Google+0

9 thoughts on “Tip #767: Server-to-server authentication is here

  1. Dibutil says:

    What about licensing of such a client?

    • Dibutil,

      that’s the best part – no license is required for the application users.


      • Mariusz says:

        Have You got some article from Microsoft that say so? I just want to be clear about that, because it would be awesome, and I don’t think so ;).

        • Mariusz,

          understand the skeptisizm. That’s why I put hyperlinks in the article. They usually point to something.

          As far as an official statement regarding application user is concerned, I expect something to appear in the next drop of licensing guide. As for now, I’m content with assuming that application user does not need a license. To start with, there is nowhere to define the license even if you wanted to.


    • Tracy,

      most of the posts you mention are quite old (by internet standards). S2S authentication has become available for Dynamics 365 not so long ago (one of the stackoverflow posts does mention that) and you’d need an updated ADAL library to get it all going. What I posted has been tried and tested; but, of course, your mileage may vary.

      Also worth noting that some of the posts refer to username/password authentication while the code I’m referring to uses clientid/secret credentials. Could be the source of misbehaviour as well.


  2. PhuocLe says:

    I get the error, can you help me

    System.ServiceModel.Security.MessageSecurityException: ‘The HTTP request is unauthorized with client authentication scheme ‘Anonymous’. The authentication header received from the server was ‘Bearer authorization_uri=https://login.windows.net/12b5c856-99c8-4268-b99f-b5bfd02ae0f3/oauth2/authorize, resource_id=https://xxxxxx.crm.dynamics.com/’.’

    WebException: The remote server returned an error: (401) Unauthorized.

    • HI PhuocLe,

      this error usually is a result of incorrect credentials (either client id or secret in S2S scenario). If you could paste the code snippet and point to the line throwing that exception, we can tourbleshoot it further.


  3. Rohit Iyer says:

    This is brilliant, great article, this worked for me like a charm!!!

Leave a Reply

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