Динамический CRM API HttpClient Запрос аутентификации с помощью ADFS 3.0 - PullRequest
0 голосов
/ 30 октября 2018

У меня есть локальная версия Dynamic CRM (2016), которая настроена на ADFS (3.0). Когда пользователь хочет войти в систему, он перенаправляется на страницу входа в ADFS, и пользователь вводит свои учетные данные Windows AD.

Из основного приложения .net мне нужно сделать запрос к API CRM с помощью HttpClient. Когда я пытаюсь отправить учетные данные, как обычно для Windows Auth CRM, это не работает. Я получаю 401 Несанкционированный. Как ниже.

HttpClient client = new HttpClient(new HttpClientHandler() { Credentials = new NetworkCredential("myuser", "mypassword", "mydomain") });
var result = client.GetAsync("https://mycrmaddress/api/data/v8.0/accounts");

Я также пытался использовать Adal, чтобы получить токен и прикрепить его как токен на предъявителя к запросу, но я не могу получить токен с adal. При попытке получить следующее:

The authorization server does not support the requested 'grant_type'. The authorization server only supports 'authorization_code'

ADFS 3.0 не поддерживает этот поток.

Я не могу выполнить обновление до ADFS 4.0, поэтому мне хотелось бы узнать, какие у меня есть варианты для выполнения аутентифицированного вызова CRM API (без запроса окна входа в систему, так как это приложение является службой).

Могу ли я выполнить какие-либо настройки в ADFS, чтобы мой первый пример работал? Или это возможно сделать с Adal, даже если это ADFS 3.0? Или любое другое решение ...

1 Ответ

0 голосов
/ 01 ноября 2018

Я нашел ответ на свой вопрос. Это немного хакерски, но я сам проверил, и это работает. В качестве временного решения это поможет.

Подробности доступны здесь: https://community.dynamics.com/crm/f/117/t/255985


ADFS 3.0 поддерживает поток кода авторизации и это то, что мы будем использовать в этом случае.

  • Нам нужно получить код авторизации. Обычно на этих шагах пользователю предлагается ввести окно для ввода его учетных данных. Выполнив POST и отправив имя пользователя / пароль, можно получить код авторизации.

    • {authProvider} - ADFS Uri - что-то вроде https://adfs.mycompany.com/adfs/oauth2/
    • {ClientId} - Guid используется для вашей инфраструктурной командой, чтобы добавить ваше приложение в ADFS
    • {RedirectUri} - URI IFD для динамики - должен соответствовать перенаправлению URL, используемый вашей инфраструктурной командой для добавления приложения в ADFS
    • username - Пользователь, настроенный в ADFS и в Dynamics
    • пароль - пароль для указанного выше пользователя

Затем мы делаем следующий вызов с этой информацией, используя HttpClient.

var uri = $"{authProvider}authorize?response_type=code&client_id={clientId}&resource={redirectUri}&redirect_uri={redirectUri}";

var content = new FormUrlEncodedContent(new[] {
    new KeyValuePair<string,string>("username",username),
    new KeyValuePair<string,string>("password",password),
});

var responseResult = _httpManager.PostAsync(uri, content).Result;

Содержимым ответа будет HTML-страница (обычно помните, что этот поток запрашивает у пользователя страницу входа). На этой странице будет форма, которая содержит код авторизации. используя библиотеку типа HtmlAgilityPack, получить токен. Это хакерская часть решения.

  1. Теперь, когда у нас есть код авторизации, нам нужно получить токен доступа.

Для этого нам нужно сделать следующий звонок

var uri = $"{authProvider}token";
            var content = new FormUrlEncodedContent(new[] {
                new KeyValuePair<string,string>("grant_type","authorization_code"),
                new KeyValuePair<string,string>("client_id",clientId),
                new KeyValuePair<string,string>("redirect_uri",redirectUri),
                new KeyValuePair<string,string>("code",code)
            });

var response = await _httpManager.PostAsync(uri, content);

Содержимым ответа будет строка json, которая будет содержать токен доступа.

  1. Используя токен доступа, позвоните в CRM rest API.

Вам нужно будет прикрепить токен к HttpClient в заголовке как токен на предъявителя.

httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer",token);
httpClient.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0");
httpClient.DefaultRequestHeaders.Add("OData-Version", "4.0");

С этого момента вы можете совершать звонки в CRM API, и вы будете авторизованы. Однако будьте осторожны, обычно токены недолговечны. Вам нужно будет либо увеличить срок их службы, либо запрашивать новый токен каждый раз, когда он истекает.

...