Почтальон не подключается к API Dynamics365 с использованием учетных данных клиента Oauth, консольное приложение работает с теми же данными

Я пытаюсь подключиться к Postman к Dynamics365 CRM REST API. Хотя я успешно получаю токен без входа в систему, используя учетные данные клиента Grant Type, я получаю ошибку 401 при выполнении образца GET для API. Однако мое консольное приложение работает успешно и не предлагает пользователю войти в систему (я не хочу, чтобы появлялось приглашение для входа).

У меня есть: 1. Зарегистрировал приложение в Azure AD, 2. Создал секрет клиента 3. Создал пользователя приложения в Dynamics и связал через идентификатор приложения с приложением из шага 1.

Я сделал это с двумя разными приложениями и двумя разными пользователями приложений и получил тот же результат в Postman, то есть токен получен, но ошибка 401 при GET.

Консольное приложение ниже работает с теми же учетными данными, будет признателен за любой вклад в то, что отсутствует в конфигурации Postman.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System.Net.Http.Headers;
using System.Net.Http;
using Newtonsoft.Json.Linq;
namespace ConsoleApp8
{
    class Program
    {
        static void Main(string[] args)
        {
            const string ResourceId = "https://myurldev.crm4.dynamics.com/api/data/v9.1";
            Task<AuthenticationResult> t = GetUserOAuthToken();
            t.Wait();
            string accessToken = t.Result.AccessToken;
            Console.WriteLine("ACCESS TOKEN \n\n" + accessToken);
            Console.WriteLine("\n\n Please any key to display content of the blob");

            //Console.ReadKey();

            using (HttpClient httpClient = new HttpClient())
            {
                httpClient.BaseAddress = new Uri(ResourceId);
                httpClient.Timeout = new TimeSpan(0, 2, 0);  // 2 minutes  
                httpClient.DefaultRequestHeaders.Authorization =
                    new AuthenticationHeaderValue("Bearer", accessToken);
                //Send the Get Incident request to the Web API using a GET request. 
                var response = httpClient.GetAsync("/incidents",
                        HttpCompletionOption.ResponseHeadersRead).Result;
                if (response.IsSuccessStatusCode)
                {
                    //Get the response content and parse it.

                    JObject body = JObject.Parse(response.Content.ReadAsStringAsync().Result);


                    string title = (string)body["title"];
                    Console.WriteLine("Incident title is : {0}", title);
                }
                else
                {
                    Console.WriteLine("The request failed with a status of '{0}'",
                           response.ReasonPhrase);
                }
            }

            /*
            // Use the access token to create the storage credentials. 

            TokenCredential tokenCredential = new TokenCredential(accessToken);
            StorageCredentials storageCredentials = new StorageCredentials(tokenCredential);

            // Create a block blob using those credentials 

            CloudBlockBlob blob = new CloudBlockBlob(new Uri("https://placeholderURL/SalesOrder.json"), storageCredentials);
            using (var stream = blob.OpenRead())
            {
                using (StreamReader reader = new StreamReader(stream))
                {
                    while (!reader.EndOfStream)
                    {
                        Console.WriteLine(reader.ReadLine());
                    }

                }
            }
            Console.WriteLine("\n\n Please any key to terminate the program");
            Console.ReadKey();*/
        }

        static async Task<AuthenticationResult> GetUserOAuthToken()
        {
            const string ResourceId = "https://myurldev.crm4.dynamics.com/";
            const string AuthInstance = "https://login.microsoftonline.com/{0}/";
            const string TenantId = "XXXX-DYNAMICS_TENANT_ID-XXXXX"; // Tenant or directory ID 

            // Construct the authority string from the Azure AD OAuth endpoint and the tenant ID.  
            string authority = string.Format(System.Globalization.CultureInfo.InvariantCulture, AuthInstance, TenantId);
            AuthenticationContext authContext = new AuthenticationContext(authority);
            ClientCredential cc = new ClientCredential("XXXX_APPLICATION_ID_XXXX", "XXXXX_CLIENT_SECRET_XXXX");

            // Acquire an access token from Azure AD.  
            AuthenticationResult result = await authContext.AcquireTokenAsync(ResourceId, cc);
            return result;
        }
    }
}

ПОЧТОВЫЕ ТОКЕНЫ ПЕРЕМЕННЫЕ

ПОЧТАЛЬНЫЙ ЗАПРОС И ОТВЕТ

Я уже добавил следующие разрешения в свое приложение Почтальон не подключается к API Dynamics365 с использованием учетных данных клиента Oauth, консольное приложение работает с теми же данными

Это ответ, когда я анализирую токен в JWT.io Почтальон не подключается к API Dynamics365 с использованием учетных данных клиента Oauth, консольное приложение работает с теми же данными

После того, как вы зарегистрировали свое приложение, я полагаю, вы дали приложению роли безопасности?? Кроме того, вы используете правильную среду, в которой вы предоставили данные доступа с помощью своего токена доступа.

AnkUser 22.06.2019 16:44

Да, я добавил разрешение API олицетворения пользователя в AD. Я также назначил пользовательскую роль безопасности пользователю приложения в Dynamics. Консольное приложение правильно подключается и возвращает данные. Это просто Почтальон терпит неудачу.

Earl_of_Duke 22.06.2019 16:57

Проверьте свой токен в jwt-декодер и убедитесь, что у вас есть соответствующее разрешение, например это.

Md Farid Uddin Kiron 23.06.2019 06:18

Спасибо за ваш вклад. Я обновил исходный вопрос снимком экрана с разрешениями и анализом токенов в декодере jwt (хотя я не совсем уверен, как интерпретировать ответ).

Earl_of_Duke 23.06.2019 13:04

Привет @Tony Ju, спасибо за ваш ответ и комментарий. Я считаю, что авторизация делегированных пользователей в Dynamics не является проблемой, поскольку консольное приложение может возвращать результаты с теми же учетными данными. Я также могу вручную создать POST / GET, который получает токен и может извлекать информацию. Я считаю, что проблема в том, что почтальон не отправляет необходимый идентификатор ресурса в запросе токена. Как только я подтвержу, я обновлю вопрос с разрешением. Еще раз спасибо за ваш вклад.

Earl_of_Duke 24.06.2019 18:27
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
Как установить LAMP Stack 1/2 на Azure Linux VM
Как установить LAMP Stack 1/2 на Azure Linux VM
В дополнение к нашему предыдущему сообщению о намерении Azure прекратить поддержку Azure Database для MySQL в качестве единого сервера после 16...
0
5
699
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Кажется, что Dynamics CRM поддерживает только делегированное разрешение, которые позволяют приложению получать доступ к Common Data Service выступая в роли пользователей в организации. Это означает, что учетные данные клиента здесь не подходят.

Однако вы сказали, что можете использовать учетные данные клиента в консольном приложении. Вы можете попробовать с запросом ниже, чтобы получить токен доступа.

Спасибо за отзыв. Разрешения делегирования — это единственный доступный в настоящее время вариант, и из-за ограничений вызывающего приложения и желания не показывать всплывающее окно для входа в систему это лучший вариант для нас. Я принял ваше замечание о добавлении ресурса в тело запроса токена, и это сработало, так что большое спасибо за вашу помощь!

Earl_of_Duke 25.06.2019 10:19

Другие вопросы по теме