Я пытаюсь связаться с Почтальоном с Dynamics365 CRM REST API.Хотя я успешно получаю токен без входа в систему с использованием учетных данных клиента типа «Грант», я получаю ошибку 401 при выполнении примера GET для API.Однако мое консольное приложение работает успешно и не запрашивает у пользователя логин (я не хочу, чтобы отображалось приглашение для входа в систему).
У меня есть: 1. Зарегистрировано приложение в Azure AD, 2. Созданосекрет клиента 3. Создал пользователя приложения в Dynamics и связал его с помощью идентификатора приложения с шага 1
. Я сделал это с двумя разными приложениями и двумя разными пользователями приложения и получил тот же результат в Postman, т.е. Tokenполучено, но ошибка 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;
}
}
}
POSTMAN TOKENПЕРЕМЕННЫЕ
ЗАПРОС И ОТВЕТ ПОСТМАНА
Я уже добавил следующие разрешения в мое приложение
Это ответ, когда я анализирую токен в JWT.io