首页 > 解决方案 > 未授权调用 Dynamics 365 端点

问题描述

我正在调用 Dynamics 365 端点来执行查询:

https://dev-xxx-ssp.api.crm6.dynamics.com/api/data/v9.1/accounts?$select=name

为此,我使用以下代码进行身份验证:

ClientCredential clientCredential = new ClientCredential("9cd8fe45-xxxx-xxxx-xxxx-e43ef81c803f", "abcdefghij");
AuthenticationContext authenticationContext = new AuthenticationContext("https://login.microsoftonline.com/our-domain.onmicrosoft.com");
AuthenticationResult authenticationResult = authenticationContext.AcquireTokenAsync("https://dev-xxx-ssp.api.crm6.dynamics.com/", clientCredential).Result;

然后我初始化 HttpClient:

HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://dev-xxx-ssp.api.crm6.dynamics.com/");
client.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0");
client.DefaultRequestHeaders.Add("OData-Version", "4.0");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authenticationResult.AccessToken);

这样做后我可以看到 HttpClient 有一个授权令牌,例如:

{Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IndVTG1ZZnNxZFF1V3RWXy1oeFZ0REpKWk00USIsImtpZCI6IndVTG1ZZnNxZFF1V3RWXy1oeFZ0REpKWk00USJ9.eyJhdWQiOiJodHRwczovL2Rldi1hZWMtc3NwLmFwaS5jcm02LmR5bmFtaWNzLmNvbS8iLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC80NjkyNTg2OC1kYTNlLTRkODUtYjI2Ny02ZDdhM2U5NDdhM2MvIiwiaWF0IjoxNTQ0MTQyMTA4LCJuYmYiOjE1NDQxNDIxMDgsImV4cCI6MTU0NDE0NjAwOCwiYWlvIjoiNDJSZ1lMZ3VJSDNxejRSL3IzcVphcUl2emp0MUNBQT0iLCJhcHBpZCI6IjljZDhmZTQ1LTY5ZjItNGMzNi05ZmVmLWU0M2VmODFjODAzZiIsImFwcGlkYWNyIjoiMSIsImlkcCI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzQ2OTI1ODY4LWRhM2UtNGQ4NS1iMjY3LTZkN2EzZTk0N2EzYy8iLCJvaWQiOiJmZWQzZjU3My01NTlkLTQ1ZjUtYjQxZC1kNzZlMzQ3NTFlZDAiLCJzdWIiOiJmZWQzZjU3My01NTlkLTQ1ZjUtYjQxZC1kNzZlMzQ3NTFlZDAiLCJ0aWQiOiI0NjkyNTg2OC1kYTNlLTRkODUtYjI2Ny02ZDdhM2U5NDdhM2MiLCJ1dGkiOiJuaEdRcGtaVGswQ0ZoaGRrUUJRSkFBIiwidmVyIjoiMS4wIn0.AN8CcEBluMJPBtpbqv4Q6V3dO75Y8whoBRw_Nk6u4RhbWAz1BRIIeIBNGBNneJ0Zlnfh-7_W_TH_jAiQNIJxmGhQLOTFKYxXvvq3ksS-efqdGZlwY0dU7LGM-nxDxVZhfnW18F2yBE0skRLMmB27RyCHbIkU6S5HKTfq8LEIvCaUILh00wSItTXFX1ew14T3_6yZ81x_A-d1cc_oPPbRssIlXmD8ybYVfCjc_v57TuyR1pLf2HnlK04w2ioB0KJ545BCD6nJyuC0iL_2YKdGuHxHIrbRZShu-SGihXmugRgBYl3kF-zCDiWlxAIz9F2WyMWylM1qfDnIUZrgDowxbQ}

然后我执行一个查询:

HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "https://dev-xxx-ssp.api.crm6.dynamics.com/api/data/v9.1/accounts?$select=name");
request.Headers.Add("Prefer", "odata.maxpagesize=10");
request.Headers.Add("Prefer", "odata.include-annotations=OData.Community.Display.V1.FormattedValue");
HttpResponseMessage response = this.Client.SendAsync(request).Result;
if (response.StatusCode == HttpStatusCode.OK)
{
  // ...
} else {
  throw new Exception(String.Concat("Dynamics query returned unexpected status: ", response.StatusCode.ToString())
}

此时我得到一个未经授权的状态代码,我将其捕获在我的 if 分支中并作为异常抛出。

关于如何解决这个问题的任何想法?

标签: c#azuredynamics-crmazure-active-directory

解决方案


可能是使用没有访问权限的错误用户登录。可以像这样获取和检查用户信息:

UserInfo user = authenticationResult.UserInfo;

PromptBehavior.Always枚举作为参数添加到AcquireToken()方法会强制登录对话框提示,即使缓存中存在令牌。所以你可以尝试其他身份。

AuthenticationResult authenticationResult 
        = authenticationContext.AcquireToken(resource, applicationId, new Uri(redirectUrl), PromptBehavior.Always);

推荐阅读