我们计划从组织服务转移到公共数据服务Web API,这样我们就可以使用OAuth 2.0身份验证,而不是一个客户有一些安全顾虑的服务帐户。
完成一些原型之后,我们发现Web身份验证与典型的Graph身份验证略有不同。它只支持委托权限。因此,必须提供用于获取访问令牌的用户凭证。
以下是用于CRM Web API的Azure AD Graph权限:

下面是在Web全球发现服务示例(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);这是另一个类似的帖子使用OAuth连接到Dynamic365个客户参与web服务,尽管它已经超过一年了。
您知道MS什么时候会支持应用程序权限来完全消除用户的身份验证吗?或者有任何特殊的理由让用户留在这里。谢谢你的见解。
更新1,下面是James的答案,我对代码做了修改,这是我的代码
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",我将能够得到正确的结果。如果我使用带有"https://login.microsoftonline.com/common/oauth2/authorize“的MSAL,它将无法工作,我会得到未经授权的错误。如果我使用的是阿达尔 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);
}发布于 2019-08-12 16:32:02
文档不是最容易理解的,但据我所知,您应该从在通用数据服务中使用OAuth开始。
在注册应用程序时,您有两个微妙的选项。第二种方法不需要Access Dynamic365/Common作为组织用户的权限
如果您的应用程序是允许通过身份验证的用户执行操作的客户端,则必须将应用程序配置为具有组织用户委托权限的Access Dynamic365。
或
如果应用程序将使用服务器到服务器(S2S)身份验证,则不需要执行此步骤。该配置需要一个特定的系统用户,操作将由该用户帐户执行,而不是任何必须经过身份验证的用户。
对此将作进一步阐述。
您将创建的一些应用程序并不打算由用户以交互方式运行。..。在这些情况下,您可以创建一个特殊的应用程序用户,它绑定到Azure Active Directory注册应用程序,并使用为应用程序配置的密钥秘密或上载X.509证书。这种方法的另一个好处是它不使用付费许可。 注册您的应用程序 在注册应用程序时,您遵循许多相同的步骤..。除下列情况外:
您仍将在Dynamic中有一个系统用户记录来表示应用程序注册。这支持一系列基本的动态行为,并允许您将Dynamics应用到应用程序中。
相对于用户名和密码,您可以使用这个秘密进行连接。
string serviceUrl = "https://yourorg.crm.dynamics.com";
string clientId = "<your app id>";
string secret = "<your app secret>";
AuthenticationContext authContext = new AuthenticationContext("https://login.microsoftonline.com/common", false);
ClientCredential credential = new ClientCredential(clientId, secret);
AuthenticationResult result = authContext.AcquireToken(serviceUrl, credential);
string accessToken = result.AccessToken;或者一张证书。
string CertThumbPrintId = "DC6C689022C905EA5F812B51F1574ED10F256FF6";
string AppID = "545ce4df-95a6-4115-ac2f-e8e5546e79af";
string InstanceUri = "https://yourorg.crm.dynamics.com";
string ConnectionStr = $@"AuthType=Certificate;
SkipDiscovery=true;url={InstanceUri};
thumbprint={CertThumbPrintId};
ClientId={AppID};
RequireNewInstance=true";
using (CrmServiceClient svc = new CrmServiceClient(ConnectionStr))
{
if (svc.IsReady)
{
...
}
}您还可能希望查看使用服务器到服务器(S2S)身份验证构建web应用程序,它看起来类似(但不一样)。
使用服务器到服务器(S2S)身份验证可以安全、无缝地与web应用程序和服务进行公共数据服务通信。S2S身份验证是在微软AppSource上注册的应用程序访问其订阅者的公共数据服务数据的常用方式。..。应用程序根据由Azure AD对象ID值标识的服务主体进行身份验证,该值存储在应用程序用户记录中,而不是用户凭据。
此外,如果您目前使用的是组织服务.NET对象,则在内部将其迁移到使用Web。
Dynamic365SDK程序集将被更新为使用Web。此更新将对您完全透明,并支持使用SDK本身编写的任何代码。
https://stackoverflow.com/questions/57463266
复制相似问题