首页 文章

使用ADFS 3.0进行动态CRM api HttpClient请求身份验证

提问于
浏览
1

我有一个使用ADFS(3.0)配置的内部动态CRM(2016) . 当用户想要登录时,他们会被重定向到ADFS登录页面,并且用户输入他们的Windows AD凭据 .

从.net核心应用程序我需要使用HttpClient向CRM api发出请求 . 当我尝试发送像我通常用于Windows Auth CRM的凭据时,它不起作用 . 我得到401未经授权 . 如下 .

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一起使用?或任何其他解决方案......

1 回答

  • 1

    我找到了问题的答案 . 这有点hackish,但我自己测试了它,它的工作原理 . 作为临时解决方案,这将解决问题 .

    详情请见:https://community.dynamics.com/crm/f/117/t/255985


    ADFS 3.0支持授权代码流,我们将在这种情况下使用它 .

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

    • - ADFS Uri - 类似于https://adfs.mycompany.com/adfs/oauth2/

    • - 您的基础架构团队用于将您的应用程序添加到ADFS的Guid

    • - 动态的IFD Uri - 应该与您的基础架构团队用于将您的应用程序添加到ADFS的重定向Url相匹配

    • username - 用户在ADFS和Dynamics中设置

    • 密码 - 上述用户的密码

    然后我们使用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这样的库来检索令牌 . 这是解决方案的黑客部分 .

    • 现在我们有了授权码,我们需要检索一个访问令牌 .

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

    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字符串 .

    • 使用访问令牌,调用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,您将获得授权 . 但是要小心,通常访问令牌是短暂的 . 您将需要增加其生命周期或每次过期时请求新令牌 .

相关问题