We are writing a WCF service which has to integrate with Dynamics CRM 2016 Online. I\'m trying to authenticate using ADAL, using method AcquireTokenAsync()
. Pro
For what it's worth without using ADAL
var postData = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("resource", cred.ResourceId),
new KeyValuePair<string, string>("grant_type", "client_credentials"),
new KeyValuePair<string, string>("client_id", cred.ClientId),
new KeyValuePair<string, string>("client_secret", cred.ClientSecret),
};
using (var client = new HttpClient()) {
string baseUrl = "https://login.windows.net/YourAADInstanceName.onmicrosoft.com/oauth2/";
client.BaseAddress = new Uri(baseUrl);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var content = new FormUrlEncodedContent(postData);
HttpResponseMessage response = await client.PostAsync("token", content);
string jsonString = await response.Content.ReadAsStringAsync();
var responseData = JsonConvert.DeserializeObject<Token>(jsonString);
return responseData;
}
private static string API_BASE_URL = "https://<CRM DOMAIN>.com/";
private static string API_URL = "https://<CRM DOMAIN>.com/api/data/v8.1/";
private static string CLIENT_ID = "<CLIENT ID>";
static void Main(string[] args)
{
var ap = AuthenticationParameters.CreateFromResourceUrlAsync(
new Uri(API_URL)).Result;
var authContext = new AuthenticationContext(ap.Authority, false);
var userCredential = new UserCredential("<USERNAME>", "<PASSWORD>");
var result = authContext.AcquireToken(API_BASE_URL, CLIENT_ID, userCredential);
var httpClient = HttpWebRequest.CreateHttp(Path.Combine(API_URL, "accounts"));
httpClient.Headers.Add(HttpRequestHeader.Authorization, "Bearer:" + result.AccessToken);
using (var sr = new StreamReader(httpClient.GetResponse().GetResponseStream()))
{
Console.WriteLine(sr.ReadToEnd());
}
}
Note: I'm using an older version of ADAL (2.19.208020213) as it appears the password parameter has been taken out of the UserCredential constructor.
EDIT: Latest versions of ADAL have UserPasswordCredential which can be used in place of UserCredential
(and probably was added as soon as Password
was removed from UserCredential
)
EDIT 2: CRM now supports Server to Server Authentication which allows you to create an application user.
Okay, ended up finding a solution for this.
Provided you have registered your application with Azure AD (as a Web App / Web API, not a Native Application), you will receive a client ID and a secret key for that application.
The code to acquire the token without having a pop-up window is as follows:
AuthenticationParameters ap = AuthenticationParameters.CreateFromResourceUrlAsync(
new Uri(resource+"/api/data/v8.1")).Result;
AuthenticationContext ac = new AuthenticationContext(ap.Authority);
AuthenticationResult r = await ac.AcquireTokenAsync(ap.Resource, new ClientCredential(clientId,clientSecret));
resource is the base URL of your Dynamics CRM deployment.
Authentication parameters are discovered at run time as suggested in this MSDN acticle.