I am having trouble making an HTTP GET request to our Dynamics CRM 2016 web API for a proof-of-concept.
I have followed this walk-through to create a multi-tenant web app set up on Azure Active Directory, which has been granted access to Dynamics CRM as an organisation user.
I used this example code in order to obtain an access token. This appears to work, providing me with what looks like a valid token.
I do a simple GET request using the token, which fails with a 401 Unauthorized
. The code:
class Test
{
public async Task RunAsync()
{
var resource = "https://<snip>.crm4.dynamics.com/api/data/v8.1/";
var authParams = AuthenticationParameters.CreateFromResourceUrlAsync(new Uri(resource))
.Result;
var authorityUrl = authParams.Authority;
var resourceUrl = authParams.Resource;
var clientId = "<snip>";
var client_secret = "<snip>";
var clientCredential = new ClientCredential(clientId, client_secret);
var authContext = new AuthenticationContext(authorityUrl, false);
var token = authContext.AcquireToken(resourceUrl, clientCredential);
var response = await CallApiAsync($"{resourceUrl}api/data/v8.1/accounts?$select=name&$top=3", token.AccessToken);
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(response.RequestMessage);
Console.WriteLine(response.Headers);
Console.WriteLine(response.ReasonPhrase);
Console.WriteLine(content);
}
private async Task<HttpResponseMessage> CallApiAsync(string uri, string token)
{
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", token);
httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
httpClient.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0");
httpClient.DefaultRequestHeaders.Add("OData-Version", "4.0");
return await httpClient.GetAsync(uri);
}
}
}
The request:
Method: GET, RequestUri: 'https://<snip>.crm4.dynamics.com/api/data/v8.1/accounts?$select=name&$top=3', Version: 1.1, Content: <null>, Headers:
{
Authorization: Bearer <snip>
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
}
Response:
REQ_ID: <snip>
Strict-Transport-Security: max-age=31536000; includeSubDomains
Date: Tue, 21 Feb 2017 15:08:39 GMT
Set-Cookie: crmf5cookie=<snip>;secure; path=/
Server: Microsoft-IIS/8.5
WWW-Authenticate: Bearer authorization_uri=https://login.windows.net/<snip>/oauth2/authorize,resource_id=https://<snip>.crm4.dynamics.com/
X-Powered-By: ASP.NET
Unauthorized
HTTP Error 401 - Unauthorized: Access is denied
I feel like I'm missing something obvious?
There is no CRM organization user being used. Check out this Server to Server Auth tutorial. You'll need to create an application user. There is a little more commentary here on the Tip of the Day for Server to Server Auth.
Outside of Server to Server Auth you can authenticate as a CRM user using creds this way.