首页 文章

将WebApp授权给ADFS以访问Dynamics CRM Web API

提问于
浏览
14

我有一个需要与Dynamic CRM 365 Web API对话的Web应用程序 . 动态CRM在ADFS上配置为依赖方 . 服务器是Windows Server 2016,一切都是内部部署,而不是Azure .

我为获取有效令牌所做的工作如下:

1)在ADFS中,转到应用程序组并添加新的服务器应用程序,获取ClientID并为我的Web应用程序生成客户机密钥 .

enter image description here

2)在Active Directory中添加新的用户webAppUser

3)将此用户添加为 an Application User in CRM ,其中应用程序ID是我在将Web应用程序注册到ADFS时之前获得的ClientID . 还创建了一个具有实体帐户完全权限的新角色,并将此角色分配给此应用程序用户

4)我正在使用以下代码来检索承载令牌并将其添加到我的HttpClient Authorization标头中 .

public class CrmWebApiClient
{
    private HttpClient _httpClient;

    public CrmWebApiClient()
    {
        _httpClient = new HttpClient();
        _httpClient.BaseAddress = new Uri("https://crmbaseaddress.com");            
    }

    internal async Task Initialize()
    {
        try
        {               
            var authority = "https://adfsServerUrl/adfs/";
            var authContext = new AuthenticationContext(authority,false);
            var credentials = new ClientCredential(clientID,clientSecret);

            var authResult = await authContext.AcquireTokenAsync("https://crmbaseaddress.com", credentials);

            _httpClient.DefaultRequestHeaders.Authorization =
                new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
        }
        catch (Exception ex)
        {
            var error = ex;
        }

    }

    internal async Task<string> GetValuesAsync()
    {
        var result = string.Empty;
        try
        {
            result = await _httpClient.GetStringAsync("api/data/v8.1/accounts");
        }
        catch (Exception ex)
        {
            var error = ex;
        }

        return result;
    }
}

5)我设法得到一个令牌,但当我打电话给CRM的Web Api时,我仍然得到401 Unauthorized .

你能帮我么?我在正确的道路上吗?我该怎么办?

1 回答

  • 3

    最后,我必须使用系统用户并使用以下代码在我的oAUth请求中发送其凭据,以获取有效令牌:

    namespace TestApp.App_Start {
    public class CrmWebApiClient
    {
        private HttpClient _httpClient;
    
        public CrmWebApiClient()
        {       
            _httpClient = new HttpClient();
            _httpClient.BaseAddress = new Uri("https://crmUrl");
            _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            _httpClient.DefaultRequestHeaders.Add("OData-MaxVersion","4.0");
            _httpClient.DefaultRequestHeaders.Add("OData-Version", "4.0");
        }
    
        internal async Task Initilize()
        {
            try
            {
    
                var tokenClient = new HttpClient();             
                var content = new FormUrlEncodedContent(new[] {
                    new KeyValuePair<string,string>("client_id",_clientID),
                    new KeyValuePair<string,string>("client_secret",_clientSecret),
                    new KeyValuePair<string,string>("resource",_urlOfResource),
                    new KeyValuePair<string,string>("username",_usernameOfSystemUser),
                    new KeyValuePair<string,string>("password",_passwordOfSystemUser),
                    new KeyValuePair<string,string>("grant_type","password"),
                });
                var res = tokenClient.PostAsync("https://adfsUrl/adfs/oauth2/token", content);
                var respo = res.Result.Content.ReadAsStringAsync().Result;
                var accesstoken = JObject.Parse(respo).GetValue("access_token").ToString();
    
                _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accesstoken);
    
            }
            catch (Exception ex)
            {
                Trace.WriteLine($"Exception when requesting the bearer token from ADFS: {ex.Message} - {ex.InnerException?.Message}");
            }
    
        }
    
        internal async Task<string> GetAccountsAsync()
        {
            var result = string.Empty;
            try
            {
                result = _httpClient.GetStringAsync("/api/data/v8.0/accounts").Result;
    
            }
            catch (Exception ex)
            {
                Trace.WriteLine($"Exception when calling the CRM api: {ex.Message} - {ex.InnerException?.Message}");
            }
            return result;
        }
    }
    }
    
    
    // Use the above class like that
    var httpClient = new CrmWebApiClient();
    httpClient.Initilize().Wait();
    var result = httpClient.GetAccountsAsync().Result;
    

相关问题