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 для получения дополнительной информации о том, как это сделать.