401- Несанкционированная аутентификация с использованием REST API Dynamics CRM с Azure AD
Я пытаюсь получить доступ к интерактивному REST API Dynamics CRM с помощью аутентификации Azure AD oAuth 2. Для этого я выполнил следующие шаги:
- Я зарегистрировал веб-приложение и/или веб-api в Azure
- Настроить разрешения для Dynamics CRM для делегирования разрешений "Доступ к CRM Online как пользователь организации"
- И создал ключ с истечением 1 года и сгенерировал идентификатор клиента.
После того, как веб-приложение было настроено на Azure, я создал консольное приложение в .NET/С#, которое использует ADAL для создания простого запроса, в этом случае для получения списка учетных записей:
class Program
{
private static string ApiBaseUrl = "https://xxxxx.api.crm4.dynamics.com/";
private static string ApiUrl = "https://xxxxx.api.crm4.dynamics.com/api/data/v8.1/";
private static string ClientId = "2a5dcdaf-2036-4391-a3e5-9d0852ffe3f2";
private static string AppKey = "symCaAYpYqhiMK2Gh+E1LUlfxbMy5X1sJ0/ugzM+ur0=";
static void Main(string[] args)
{
AuthenticationParameters ap = AuthenticationParameters.CreateFromResourceUrlAsync(new Uri(ApiUrl)).Result;
var clientCredential = new ClientCredential(ClientId, AppKey);
var authenticationContext = new AuthenticationContext(ap.Authority);
var authenticationResult = authenticationContext.AcquireToken(ApiBaseUrl, clientCredential);
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authenticationResult.AccessToken);
var result = httpClient.GetAsync(Path.Combine(ApiUrl, "accounts")).Result;
}
}
Я извлекаю токен доступа успешно, но когда я пытаюсь выполнить httprequest для CRM, я всегда получаю 401 - Несанкционированный код состояния. Что мне не хватает?
Ответы
Ответ 1
1 год и 2 месяца спустя этот же код отлично работает. Как отмечали многие, Dynamics 365 начала поддерживать аутентификацию между серверами (S2S). Единственным шагом, который я должен был сделать, чтобы я тогда не был, было создание пользователя приложения.
Для получения дополнительной информации о том, как выполнить эту проверку подлинности, проверьте этот веб-сайт: https://msdn.microsoft.com/en-us/library/mt790170.aspx
Ответ 2
Я бы посоветовал вам взглянуть на аутентификацию Server-to-Server (S2S), которая была добавлена в Dynamics 365 в последней версии.
Используя S2S, вам не нужна платная лицензия Dynamics 365. Вместо учетных данных пользователя приложение аутентифицируется на основе принципала службы, идентифицированного значением идентификатора объекта Azure AD, которое хранится в записи пользователя приложения Dynamics 365.
Более подробную информацию можно найти здесь:
https://msdn.microsoft.com/en-us/library/mt790168.aspx
https://msdn.microsoft.com/en-us/library/mt790170.aspx
Ответ 3
Спасибо всем за ваши ответы. Наконец, мне удалось получить доступ к API OData Dynamics CRM с помощью ADAL 3.
Поскольку у многих людей все еще есть проблемы с этим, см. следующие шаги:
Регистрация приложений
-
Войдите в portal.azure.com
с помощью администратора вашего Office 365 вашей подписки на Dynamics CRM.
-
Перейдите в Azure Active Director\App регистрации и добавьте новые регистрации приложений
-
Введите "Имя" и "URL входа", URL-адрес может быть любым (https://localhost, например)
-
Выберите зарегистрированное приложение, которое вы только что создали, перейдите в "Настройки\Ключи"
-
Введите описание ключа, нажмите "Сохранить" и скопируйте значение (и сохраните его, поскольку он понадобится вам позже). Также скопируйте идентификатор приложения зарегистрированного приложения.
-
Перейдите в раздел "Требуемые разрешения", нажмите "Добавить", выберите "Динамика CRM Online", затем отметьте "Доступ к CRM Online в качестве пользователей организации".
Эти шаги позволяют клиентскому приложению обращаться к Dynamics CRM с помощью идентификатора приложения и секретариата клиента, созданного на шаге 5.
Теперь ваше клиентское приложение может аутентифицироваться против Azure AD с разрешения на доступ к CRM Online. Однако CRM Online не знает об этом "клиентском приложении" или "пользователе". CRM API ответит на 401, если вы попытаетесь получить к нему доступ.
Добавить пользователя приложения CRM
Чтобы CRM знал о "клиентском приложении" или "пользователе", вам нужно добавить пользователя приложения.
-
Перейдите в раздел CRM\Security Roles, создайте новую роль безопасности или просто скопируйте роль "Системный администратор"
-
Перейдите в раздел CRM\Settings\Security\Users, создайте нового пользователя, измените форму на "Пользователь приложения"
-
Введите необходимые поля с идентификатором приложения, которое было на предыдущем шаге. После сохранения CRM автоматически заполнит ID объекта Azure AD и URI.
-
Добавьте пользователя в роль безопасности, созданную с предыдущего шага.
Теперь вы должны иметь доступ к CRM-API, используя HttpClient и ADAL, используя пример кода ниже:
var ap = await AuthenticationParameters.CreateFromResourceUrlAsync(
new Uri("https://*****.api.crm6.dynamics.com/api/data/v9.0/"));
String authorityUrl = ap.Authority;
String resourceUrl = ap.Resource;
var authContext = new AuthenticationContext(authorityUrl);
var clientCred = new ClientCredential("Application ID", "Client Secret");
var test = await authContext.AcquireTokenAsync(resourceUrl, clientCred);
Console.WriteLine(test.AccessToken);
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", test.AccessToken);
var response = await client.GetAsync("https://*****.api.crm6.dynamics.com/api/data/v9.0/contacts");
var contacts = await response.Content.ReadAsStringAsync();
Console.WriteLine(contacts);
}
Ответ 4
Ваш ClientId, AppKey от Azure, поэтому ap.Authority
должен быть https://login.microsoftonline.com/tenantid
в var authenticationContext = new AuthenticationContext(ap.Authority);
Ответ 5
Я не думаю, что вы сможете обойтись, предоставляя учетные данные пользователю, по крайней мере, в какой-то "учетной записи интеграции". Вы можете избежать более обычного всплывающего/перенаправляемого потока OAUTH со следующим:
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System;
using System.IO;
using System.Net;
namespace ConsoleApplication2
{
class Program
{
private static string API_BASE_URL = "https://<CRM DOMAIN>/";
private static string API_URL = "https://<CRM DOMAIN>/api/data/v8.1/";
private static string CLIENT_ID = "<CLIENT ID>";
static void Main(string[] args)
{
var userCredential = new UserCredential("<USERNAME>", "<PASSWORD>");
var authContext = new AuthenticationContext("https://login.windows.net/common", false);
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());
}
Console.ReadLine();
}
}
}
Примечание. Я использую более старую версию ADAL (2.19.208020213), поскольку, как представляется, параметр password
был принят из конструктора UserCredential
.
EDIT: CRM теперь поддерживает Server to Server Authentication, которая позволяет вам создавать пользователя приложения.
Ответ 6
Вам может потребоваться настройка пользователя приложения в CRM для соответствия с вашим Azure Application:
https://msdn.microsoft.com/en-us/library/mt790170.aspx
В то время как вы можете установить свой токен на уровне С#, веб-запрос к ресурсу CRM может завершиться неудачно из-за разрешений уровня CRM.
Ответ 7
Веб-служба CRM 365 не поддерживает доступ к токенам только для приложений.
Доказательство № 1: для API Dynamics CRM Online в Azure нет "Разрешений приложений".
![(see screenshot)]()
Доказательство №2: в инструкциях MSDN для подключения к веб-службам Microsoft Dynamics 365 с использованием OAuth - "Авторизация одобрена, когда действительный токен доступа OAuth 2.0 (пользователя), выпущенный Microsoft Azure Active Directory, предоставляется в заголовках запросов сообщений.
Это означает, что вам нужно будет предоставить учетные данные для учетной записи пользователя, которая имеет соответствующий доступ к CRM, приложение не будет выполнено. См. этот поток сообщества CRM Online для получения дополнительной информации о том, как это сделать.