我们正计划从“组织服务”迁移到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 ] 在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”权限,则可以得到正确的结果。如果我将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);
}
答案 0 :(得分:1)
该文档并不是最容易遵循的文档,但是据我了解,您应该从Use OAuth with Common Data Service开始。
注册应用程序时,您有两个微妙的选择。第二个不需要Access Dynamics 365 /公共数据服务作为组织用户权限
Giving access to Common Data Service
如果您的应用将是允许经过身份验证的用户执行以下操作的客户端 执行操作,您必须将应用程序配置为具有 作为组织用户的委派权限访问Dynamics 365。
或
如果您的应用将使用服务器到服务器(S2S)身份验证,请执行此步骤 不需要。该配置需要特定的系统用户 并且操作将由该用户帐户执行,而不是 任何必须通过身份验证的用户。
这将进一步详细说明。
您将要创建的某些应用并非旨在由以下用户交互式运行 用户。在这些情况下,您可以创建一个特殊的应用程序用户 绑定到Azure Active Directory注册的应用程序,并且 使用为应用程序配置的密钥机密或上载X.509 证书。这种方法的另一个好处是它不会 消费付费许可证。
注册您的应用
注册应用程序时,请执行许多相同的步骤... 以下例外:
- 您不需要授予Access Dynamics 365作为组织用户的权限。
您将在Dynamics中仍然有一个系统用户记录,以代表应用程序注册。这支持一系列基本的Dynamics行为,并允许您将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)
{
...
}
}
您可能还想查看Build web applications using Server-to-Server (S2S) authentication,它看起来很相似(但不同)。
使用服务器到服务器(S2S)身份验证来安全无缝地进行 通过您的Web应用程序与Common Data Service通信,并且 服务。 S2S身份验证是应用程序在其上注册的常用方法 Microsoft AppSource用于访问的通用数据服务数据 他们的订户。 ...而不是用户凭据,而是基于存储在应用程序用户记录中的Azure AD对象ID值标识的服务主体对应用程序进行身份验证。
放在一边;如果您当前正在使用Organization Service .NET对象,那么该对象将在内部迁移到使用Web API。
Microsoft Dynamics CRM 2011 endpoint
Dynamics 365 SDK程序集将更新为使用Web API。 此更新对您和任何编写的代码完全透明 将支持使用SDK本身。