首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >动态客户参与Web的应用程序权限支持

动态客户参与Web的应用程序权限支持
EN

Stack Overflow用户
提问于 2019-08-12 14:36:50
回答 1查看 519关注 0票数 2

我们计划从组织服务转移到公共数据服务Web API,这样我们就可以使用OAuth 2.0身份验证,而不是一个客户有一些安全顾虑的服务帐户。

完成一些原型之后,我们发现Web身份验证与典型的Graph身份验证略有不同。它只支持委托权限。因此,必须提供用于获取访问令牌的用户凭证。

以下是用于CRM Web API的Azure AD Graph权限:

下面是在Web全球发现服务示例(C#)中获取示例代码访问令牌的代码

代码语言:javascript
复制
  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的答案,我对代码做了修改,这是我的代码

代码语言:javascript
复制
        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);
        }
    }

因此,我能够获得访问令牌,但它仍然无法访问全局发现服务。

访问令牌如下所示:

代码语言:javascript
复制
    {
  "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,那么它并不适用于这两个权威机构。以下是工作代码:

代码语言:javascript
复制
            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);
        }
EN

回答 1

Stack Overflow用户

发布于 2019-08-12 16:32:02

文档不是最容易理解的,但据我所知,您应该从在通用数据服务中使用OAuth开始。

在注册应用程序时,您有两个微妙的选项。第二种方法不需要Access Dynamic365/Common作为组织用户的权限

允许访问共同数据服务

如果您的应用程序是允许通过身份验证的用户执行操作的客户端,则必须将应用程序配置为具有组织用户委托权限的Access Dynamic365。

如果应用程序将使用服务器到服务器(S2S)身份验证,则不需要执行此步骤。该配置需要一个特定的系统用户,操作将由该用户帐户执行,而不是任何必须经过身份验证的用户。

对此将作进一步阐述。

连接为应用程序

您将创建的一些应用程序并不打算由用户以交互方式运行。..。在这些情况下,您可以创建一个特殊的应用程序用户,它绑定到Azure Active Directory注册应用程序,并使用为应用程序配置的密钥秘密或上载X.509证书。这种方法的另一个好处是它不使用付费许可。 注册您的应用程序 在注册应用程序时,您遵循许多相同的步骤..。除下列情况外:

  • 您不需要以组织用户权限的形式授予Access Dynamics365。

您仍将在Dynamic中有一个系统用户记录来表示应用程序注册。这支持一系列基本的动态行为,并允许您将Dynamics应用到应用程序中。

相对于用户名和密码,您可以使用这个秘密进行连接。

代码语言:javascript
复制
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;

或者一张证书。

代码语言:javascript
复制
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。

Microsoft Dynamics 2011端点

Dynamic365SDK程序集将被更新为使用Web。此更新将对您完全透明,并支持使用SDK本身编写的任何代码。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57463266

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档