Postman 未使用 Oauth 客户端凭据连接到 Dynamics365 API,控制台应用程序使用相同的详细信息工作

Postman not connecting to Dynamics365 API using Oauth client credentials, console app working using same details

我正在尝试将 Postman 连接到 Dynamics365 CRM REST API。 虽然我在没有使用 Grant Type 客户端凭据登录的情况下成功获得了令牌,但在对 API 执行示例 GET 时收到 401 错误。 但是,我的控制台应用程序运行成功,没有提示用户登录(我不希望出现登录提示)。

我有: 1. 在 Azure AD 中注册应用程序, 2.创建客户端密码 3. 在 Dynamics 中创建应用程序用户并通过应用程序 ID 链接到步骤 1

中的应用程序

我用两个不同的应用程序和两个不同的应用程序用户完成了此操作,并在 Postman 中得到了相同的结果,即检索到令牌,但在 GET 时出现 401 错误。

下面的控制台应用程序使用相同的凭据,如果您能就 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 VARIABLES

POSTMAN REQUEST AND RESPONSE

我已经为我的APP添加了以下权限

这是我在JWT.io中分析token时的响应

Dynamics CRM 似乎只支持 delegated permission 允许应用程序作为组织中的用户 访问 Common Data Service 。这意味着客户端凭据在这里不合适。

但是,您说您可以在控制台应用程序中使用客户端凭据。您可以尝试使用以下请求来获取访问令牌。