Dynamics crm Dynamics客户参与Web API的应用程序权限支持
我们计划从组织服务转移到,这样我们就可以利用OAuth 2.0身份验证,而不是客户有一些安全顾虑的服务帐户 一旦我们做了一些原型,我们发现WebAPI认证与典型的GraphAPI认证有点不同。它只支持委托权限。因此,必须提供用户凭证以获取访问令牌 以下是CRM Web API的Azure AD Graph API权限: 下面是获取访问令牌的代码 这是另一个类似的帖子,虽然已经有一年多了 您知道MS何时会支持应用程序权限以完全消除用户的身份验证吗?或者有任何特殊的原因让用户留在这里。谢谢你的见解 [更新1] 下面是James的回答,我修改了代码,这是我的代码Dynamics crm Dynamics客户参与Web API的应用程序权限支持,dynamics-crm,dynamics-crm-online,dynamics-365,Dynamics Crm,Dynamics Crm Online,Dynamics 365,我们计划从组织服务转移到,这样我们就可以利用OAuth 2.0身份验证,而不是客户有一些安全顾虑的服务帐户 一旦我们做了一些原型,我们发现WebAPI认证与典型的GraphAPI认证有点不同。它只支持委托权限。因此,必须提供用户凭证以获取访问令牌 以下是CRM Web API的Azure AD Graph API权限: 下面是获取访问令牌的代码 这是另一个类似的帖子,虽然已经有一年多了 您知道MS何时会支持应用程序权限以完全消除用户的身份验证吗?或者有任何特殊的原因让用户留在这里。谢谢你的见解
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);
}
}
顺便说一下,我们已经按照说明在CRM中创建了应用程序用户
我有什么遗漏吗
[更新2]
对于WhoAmI请求,有不同的结果。如果我使用的是最新的且具有权限的“”,我将能够得到正确的结果。如果我将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);
}
文档不是最容易理解的,但据我所知,您应该从开始 在注册应用程序时,您有两个微妙的选择。第二个不需要Access Dynamics 365/公共数据服务作为组织用户权限 如果您的应用程序将是一个客户端,允许经过身份验证的用户 执行操作时,必须将应用程序配置为具有 以组织用户的委托权限访问Dynamics 365 或 如果您的应用程序将使用服务器到服务器(S2S)身份验证,请执行此步骤 不需要。该配置需要特定的系统用户 操作将由该用户帐户执行,而不是由 必须经过身份验证的任何用户 这一点将进一步阐述 您将创建的某些应用程序不打算由用户以交互方式运行 用户。。。在这些情况下,您可以创建一个特殊的应用程序用户 它绑定到Azure Active Directory注册的应用程序,并且 使用为应用程序配置的密钥密钥或上载X.509 证明书这种方法的另一个好处是它不会 使用付费许可证 注册你的应用程序 注册应用程序时,请遵循许多相同的步骤。。。和 下列例外情况:
- 您不需要授予Access Dynamics 365 as organization users权限
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;
您可能还想查看一个类似(但不同)的
使用服务器到服务器(S2S)身份验证安全无缝地
使用web应用程序和通用数据服务进行通信
服务。S2S身份验证是应用程序注册的常用方式
Microsoft AppSource用于访问的公用数据服务数据
他们的订户。。。应用程序不是基于用户凭据,而是基于由存储在应用程序用户记录中的Azure AD对象ID值标识的服务主体进行身份验证
旁白;如果您当前正在使用Organization Service.NET对象,则该对象将迁移到内部使用Web API
Dynamics 365 SDK程序集将更新为使用Web API。
此更新对您和任何编写的代码都是完全透明的
将支持使用SDK本身
谢谢James,请根据您的建议查看我的问题更新。您是否尝试过直接向Dynamics实例提交WhoAmI请求?谢谢@JamesWood,请查看上面的更新2。
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);
}
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)
{
...
}
}