【发布时间】:2019-08-12 14:36:50
【问题描述】:
我们计划从组织服务迁移到Common Data Service Web API,因此我们可以使用 OAuth 2.0 身份验证,而不是客户存在一些安全问题的服务帐户。
一旦我们做了一些原型,我们发现 Web API 身份验证与典型的 Graph API 身份验证有点不同。它仅支持委托权限。因此,必须提供用户凭证才能获取访问令牌。
这是 CRM Web API 的 Azure AD Graph API 权限:
这里是在Web API Global Discovery Service Sample (C#)获取示例代码的访问令牌的代码
string GlobalDiscoUrl = "https://globaldisco.crm.dynamics.com/";
AuthenticationContext authContext = new AuthenticationContext("https://login.microsoftonline.com", false);
UserCredential cred = new UserCredential(username, password);
AuthenticationResult authResult = authContext.AcquireToken(GlobalDiscoUrl, clientId, cred);
这是另一篇类似的帖子Connect to Dynamics 365 Customer Engagement web services using OAuth,尽管它已有一年多的历史了。
您知道 MS 什么时候会支持应用程序权限以完全消除用户的身份验证吗?或者有任何特殊原因将用户留在这里。感谢您的任何见解。
[更新 1] 根据詹姆斯的以下回答,我对代码进行了修改,这是我的代码
string clientId = "3f4b24d8-61b4-47df-8efc-1232a72c8817";
string secret = "xxxxx";
ClientCredential cred = new ClientCredential(clientId, secret);
string GlobalDiscoUrl = "https://globaldisco.crm.dynamics.com/";
AuthenticationContext authContext = new AuthenticationContext("https://login.microsoftonline.com/common", false);
AuthenticationResult authResult = authContext.AcquireToken(GlobalDiscoUrl, cred);
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
client.Timeout = new TimeSpan(0, 2, 0);
client.BaseAddress = new Uri(GlobalDiscoUrl);
HttpResponseMessage response = client.GetAsync("api/discovery/v1.0/Instances", HttpCompletionOption.ResponseHeadersRead).Result;
if (response.IsSuccessStatusCode)
{
//Get the response content and parse it.
string result = response.Content.ReadAsStringAsync().Result;
JObject body = JObject.Parse(result);
JArray values = (JArray)body.GetValue("value");
if (!values.HasValues)
{
return new List<Instance>();
}
return JsonConvert.DeserializeObject<List<Instance>>(values.ToString());
}
else
{
throw new Exception(response.ReasonPhrase);
}
}
所以我能够获取访问令牌,但它仍然无法访问全局发现服务。
访问令牌如下所示:
{
"aud": "https://globaldisco.crm.dynamics.com/",
"iss": "https://sts.windows.net/f8cdef31-a31e-4b4a-93e4-5f571e91255a/",
"iat": 1565802457,
"nbf": 1565802457,
"exp": 1565806357,
"aio": "42FgYEj59uDNtwvxTLnprU0NYt49AA==",
"appid": "3f4b24d8-61b4-47df-8efc-1232a72c8817",
"appidacr": "1",
"idp": "https://sts.windows.net/f8cdef31-a31e-4b4a-93e4-5f571e91255a/",
"tid": "f8cdef31-a31e-4b4a-93e4-5f571e91255a",
"uti": "w8uwKBSPM0y7tdsfXtAgAA",
"ver": "1.0"
}
顺便说一句,我们已经按照说明在 CRM 中创建了应用程序用户。
我在这里缺少什么?
[更新 2] 对于 WhoAmI 请求,有不同的结果。如果我使用最新的MSAL 并具有权限“https://login.microsoftonline.com/AzureADDirectoryID/oauth2/authorize”,我将能够得到正确的结果。如果我将 MSAL 与“https://login.microsoftonline.com/common/oauth2/authorize”一起使用,它将不起作用,我会收到未经授权的错误。如果我使用ADAL 2.29,它对这两个权限都不起作用。这是工作代码:
IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create("3f4b24d8-61b4-47df-8efc-1232a72cxxxx")
.WithClientSecret("xxxxxx")
// .WithAuthority("https://login.microsoftonline.com/common/oauth2/authorize", false)
.WithAuthority("https://login.microsoftonline.com/3a984a19-7f55-4ea3-a422-2d8771067f87/oauth2/authorize", false)
.Build();
var authResult = app.AcquireTokenForClient(new String[] { "https://crmxxxxx.crm5.dynamics.com/.default" }).ExecuteAsync().Result;
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
client.Timeout = new TimeSpan(0, 2, 0);
client.BaseAddress = new Uri("https://crm525842.api.crm5.dynamics.com/");
HttpResponseMessage response = client.GetAsync("api/data/v9.1/WhoAmI()", HttpCompletionOption.ResponseHeadersRead).Result;
if (response.IsSuccessStatusCode)
{
//Get the response content.
string result = response.Content.ReadAsStringAsync().Result;
Console.WriteLine(result);
}
else
{
throw new Exception(response.ReasonPhrase);
}
【问题讨论】:
-
您是否尝试过直接向您的 Dynamics 实例提交 WhoAmI 请求?
-
感谢@JamesWood,请检查上面的更新 2。
标签: dynamics-crm dynamics-crm-online dynamics-365