Refering to not answered Questions:
401- Unauthorized authentication using REST API Dynamics CRM with Azure AD
and
Dynamics CRM Online 2016 - Daemon
I finally found a solution. Provided by Joao R. in this Post:
https://community.dynamics.com/crm/f/117/t/193506
First of all: FORGET ADAL
My problem was the whole time that I was using "wrong" URLS as it seems you need other adresses when not using Adal (or more general: user-redirect).
Construct following HTTP-Reqest for the Token:
URL: https://login.windows.net/MyCompanyTenant.onmicrosoft.com/oauth2/token
Header:
Body:
Construct the following HTTP-Request for the access to WebApi:
URL: https://MyCompanyTenant.api.crm.dynamics.com/api/data/v8.0/accounts
Header:
var https = require("https");
var querystring = require("querystring");
var config = require("../config/configuration.js");
var q = require("q");
var authHost = config.oauth.host;
var authPath = config.oauth.path;
var clientId = config.app.clientId;
var resourceId = config.crm.resourceId;
var username = config.crm.serviceUser.name;
var password = config.crm.serviceUser.password;
var clientSecret =config.app.clientSecret;
function retrieveToken() {
var deferred = q.defer();
var bodyDataString = querystring.stringify({
grant_type: "password",
client_id: clientId,
resource: resourceId,
username: username,
password: password,
client_secret: clientSecret
});
var options = {
host: authHost,
path: authPath,
method: 'POST',
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Cache-Control": "no-cache"
}
};
var request = https.request(options, function(response){
// Continuously update stream with data
var body = '';
response.on('data', function(d) {
body += d;
});
response.on('end', function() {
var parsed = JSON.parse(body); //todo: try/catch
deferred.resolve(parsed.access_token);
});
});
request.on('error', function(e) {
console.log(e.message);
deferred.reject("authProvider.retrieveToken: Error retrieving the authToken: \r\n"+e.message);
});
request.end(bodyDataString);
return deferred.promise;
}
module.exports = {retrieveToken: retrieveToken};
public class AuthenticationResponse
{
public string token_type { get; set; }
public string scope { get; set; }
public int expires_in { get; set; }
public int expires_on { get; set; }
public int not_before { get; set; }
public string resource { get; set; }
public string access_token { get; set; }
public string refresh_token { get; set; }
public string id_token { get; set; }
}
private static async Task GetAuthenticationResponse()
{
List> vals = new List>();
vals.Add(new KeyValuePair("client_id", ClientId));
vals.Add(new KeyValuePair("resource", ResourceId));
vals.Add(new KeyValuePair("username", "yxcyxc@xyxc.onmicrosoft.com"));
vals.Add(new KeyValuePair("password", "yxcycx"));
vals.Add(new KeyValuePair("grant_type", "password"));
vals.Add(new KeyValuePair("client_secret", Password));
string url = string.Format("https://login.windows.net/{0}/oauth2/token", Tenant);
using (HttpClient httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
HttpContent content = new FormUrlEncodedContent(vals);
HttpResponseMessage hrm = httpClient.PostAsync(url, content).Result;
AuthenticationResponse authenticationResponse = null;
if (hrm.IsSuccessStatusCode)
{
Stream data = await hrm.Content.ReadAsStreamAsync();
DataContractJsonSerializer serializer = new
DataContractJsonSerializer(typeof(AuthenticationResponse));
authenticationResponse = (AuthenticationResponse)serializer.ReadObject(data);
}
return authenticationResponse;
}
}
private static async Task DataOperations(AuthenticationResponse authResult)
{
using (HttpClient httpClient = new HttpClient())
{
httpClient.BaseAddress = new Uri(ResourceApiId);
httpClient.Timeout = new TimeSpan(0, 2, 0); //2 minutes
httpClient.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0");
httpClient.DefaultRequestHeaders.Add("OData-Version", "4.0");
httpClient.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.access_token);
Account account = new Account();
account.name = "Test Account";
account.telephone1 = "555-555";
string content = String.Empty;
content = JsonConvert.SerializeObject(account, new JsonSerializerSettings() { DefaultValueHandling = DefaultValueHandling.Ignore });
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "api/data/v8.0/accounts");
request.Content = new StringContent(content);
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
HttpResponseMessage response = await httpClient.SendAsync(request);
if (response.IsSuccessStatusCode)
{
Console.WriteLine("Account '{0}' created.", account.name);
}
else
{
throw new Exception(String.Format("Failed to create account '{0}', reason is '{1}'."
, account.name
, response.ReasonPhrase));
}
(...)