locked
How to authenticate to Microsoft dynamics with a client secret? RRS feed

  • Question

  • I'm trying to authenticate a request to Dynamics using the app's client id and the application key. This is failing in a web app project in visual studio (debugging locally). Below is the code I'm trying to use. It looks like I'm getting an auth token back to pass in but it throws this error:

    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/....


            string organizationUrl = "https://myurl.dynamics.com";
            string clientId = "myclientid";
            string appKey = "myclientsecret";
            string aadInstance = "https://login.microsoftonline.com/";
            string tenantID = "mytenantid";
            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;
                Console.WriteLine(response.UserId);
            }
    Thursday, November 30, 2017 3:21 PM

All replies

  • Please check the SDK: SDK\SampleCode\CS\GeneralProgramming\Authentication. These helper classes can help you build your connection.
    Sunday, December 3, 2017 8:18 PM
  • Hello,

    Please refer the below code:

    using Microsoft.IdentityModel.Clients.ActiveDirectory;
    using Newtonsoft.Json.Linq;
    using System;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace CRM_365_Web_API_C_sharp
    {
        class Program
        {
    
            //My Azure Application / Client ID
            private const string ClientId = "******";
            private const string UserName = "***.onmicrosoft.com";
            private const string password = "***";
            private const string Resource = "https://****.crm.dynamics.com";
            //My Azure Active Directory Tenant Id
            private const string Authority = "https://login.microsoftonline.com/***/oauth2/authorize";
            private const string ClientSecret = "*****";
            public static string token { get; set; }
            static void Main(string[] args)
            {
                try
                {
                    Task.WaitAll(Task.Run(async () => await getToken(Authority, ClientId)));
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    Console.ReadLine();
                }
            }
    
            private static async Task<string> getToken(string Authority, string ClientId)
            {
                AuthenticationContext authContext = new AuthenticationContext(Authority, false);
                UserPasswordCredential upc = new UserPasswordCredential(UserName, password);
                var _authResult = await authContext.AcquireTokenAsync(Resource, ClientId, upc);
                token = _authResult.AccessToken;
                return _authResult.AccessToken;
            }
         
            /// <summary>
            /// Create Account Record
            /// </summary>
            /// <returns></returns>
            private async Task CreateAccountRecord()
            {
                Console.WriteLine("--Creating Account Record--");
    
                // A variable to hold Account Record
                var webClient = new WebClient();
    
                JObject accountRecord = new JObject();
                accountRecord.Add("name", "Account Name XXX");
                accountRecord.Add("accountnumber", "00112233");
    
                HttpRequestMessage createAccountReq =
                   new HttpRequestMessage(HttpMethod.Post, getVersionedWebAPIPath() + "accounts");
                createAccountReq.Content = new StringContent(accountRecord.ToString(),
                    Encoding.UTF8, "application/json");
                HttpResponseMessage createAccountRes =
                    await httpClient.SendAsync(createAccountReq);
    
                if (createAccountRes.StatusCode == HttpStatusCode.NoContent)  //204
                {
                    Console.WriteLine("Account was created.");
                    string AccUri = createAccountRes.Headers.GetValues("OData-EntityId").FirstOrDefault();
                    Console.WriteLine("Account URI: {0}", AccUri);
                }
                else
                {
                    Console.WriteLine("Failed to create contact for reason: {0}",
                        createAccountRes.ReasonPhrase);
                    throw new CrmHttpResponseException(createAccountRes.Content);
                }
            }
    
        }
    }


    Thanks and Regards.


    • Edited by Ravitheja J Monday, December 4, 2017 8:42 AM
    Monday, December 4, 2017 8:41 AM
  • Hi,

    I assume you replace the "myclientid" above appropriately?

    Otherwise, this type of thing can require you to set up your keys in Azure as a separate task.

    Your application would then connect to azure to verify your key/value pair and then be pass the token on to CRM for use. (in your clientcred variable)

    regards,

    Don

    Monday, January 8, 2018 1:16 AM