【问题标题】:Dynamics CRM api HttpClient Request Authentication with ADFS 3.0使用 ADFS 3.0 的 Dynamics CRM api HttpClient 请求身份验证
【发布时间】:2018-10-30 20:18:19
【问题描述】:

我有一个配置了 ADFS (3.0) 的本地 Dynamics CRM (2016)。当用户想要登录时,他们会被重定向到 ADFS 登录页面,并且用户输入他们的 Windows AD 凭据。

我需要从 .net 核心应用程序使用 HttpClient 向 CRM api 发出请求。当我尝试像通常发送 Windows Auth CRM 一样发送凭据时,它不起作用。我得到一个 401 Unauthorized。如下所示。

HttpClient client = new HttpClient(new HttpClientHandler() { Credentials = new NetworkCredential("myuser", "mypassword", "mydomain") });
var result = client.GetAsync("https://mycrmaddress/api/data/v8.0/accounts");

我还尝试使用 Adal 检索令牌并将其作为不记名令牌附加到请求中,但我无法使用 adal 获取令牌。当我尝试时,我收到以下信息:

The authorization server does not support the requested 'grant_type'. The authorization server only supports 'authorization_code'

ADFS 3.0 不支持此流程。

我无法升级到 ADFS 4.0,所以我想知道我有哪些选项可以对 CRM api 进行经过身份验证的调用(因为此应用程序是一项服务,所以不提示登录窗口)。

我可以在 ADFS 上进行任何配置,以便我的第一个示例有效吗?或者即使它是 ADFS 3.0 也可以使用 Adal 来实现吗?或任何其他解决方案...

【问题讨论】:

    标签: c# dynamics-crm adfs


    【解决方案1】:

    我找到了我的问题的答案。这有点骇人听闻,但我自己测试了它并且它有效。作为一个临时解决方案,这将起到作用。

    详情请点击此处:https://community.dynamics.com/crm/f/117/t/255985


    ADFS 3.0 支持授权码流程,这也是我们将在本例中使用的。

    • 我们需要检索授权码。通常在此步骤中会提示用户输入其凭据。通过执行 POST 并发送用户/密码,可以检索授权码。

      • {authProvider} - ADFS Uri - 类似于 https://adfs.mycompany.com/adfs/oauth2/
      • {ClientId} - 用于 由您的基础架构团队将您的应用程序添加到 ADFS
      • {RedirectUri} - 动态的 IFD Uri - 应该匹配重定向 您的基础架构团队用于将您的应用程序添加到的 URL ADFS
      • 用户名 - 在 ADFS 和 Dynamics 中设置的用户
      • password - 上述用户的密码

    然后我们使用 HttpClient 使用这些信息进行以下调用。

    var uri = $"{authProvider}authorize?response_type=code&client_id={clientId}&resource={redirectUri}&redirect_uri={redirectUri}";
    
    var content = new FormUrlEncodedContent(new[] {
        new KeyValuePair<string,string>("username",username),
        new KeyValuePair<string,string>("password",password),
    });
    
    var responseResult = _httpManager.PostAsync(uri, content).Result;
    

    响应内容将是一个 html 页面(通常请记住,此流程会提示用户登录页面)。在此页面中将有一个包含授权代码的表单。使用 HtmlAgilityPack 之类的库检索令牌。这是解决方案的骇人听闻的部分。

    1. 现在我们有了授权码,我们需要检索访问令牌。

    为此,我们需要进行以下调用

    var uri = $"{authProvider}token";
                var content = new FormUrlEncodedContent(new[] {
                    new KeyValuePair<string,string>("grant_type","authorization_code"),
                    new KeyValuePair<string,string>("client_id",clientId),
                    new KeyValuePair<string,string>("redirect_uri",redirectUri),
                    new KeyValuePair<string,string>("code",code)
                });
    
    var response = await _httpManager.PostAsync(uri, content);
    

    响应内容将是一个包含访问令牌的 json 字符串。

    1. 使用访问令牌,调用 CRM rest API。

    您需要将令牌作为不记名令牌附加到标头中的 HttpClient。

    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer",token);
    httpClient.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0");
    httpClient.DefaultRequestHeaders.Add("OData-Version", "4.0");
    

    从现在开始,您可以调用 CRM api 并且您将获得授权。但是要小心,通常访问令牌是短暂的。您要么需要延长它们的生命周期,要么在每次过期时请求一个新令牌。

    【讨论】:

    • 第二部分的“代码”是什么?
    猜你喜欢
    • 2021-03-26
    • 1970-01-01
    • 1970-01-01
    • 2013-11-27
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多