使用HttpClientFactory达网络核心2.1每个请求认证

时间:2019-02-01 10:36:57

标签: c# .net-core httpclientfactory

我应该如何使用HttpClientFactory返回HttpClient的实例,该实例的uri和凭据在调用时确定?

现有代码如下:

var httpClientHandler = new HttpClientHandler()
    {
        Credentials = new NetworkCredential(userName, password),
    };
HttpClient client = new HttpClient(httpClientHandler);
client.BaseAddress = new Uri(_appSetting.ServiceURI);

3 个答案:

答案 0 :(得分:0)

您在Startup类中的ConfigureServices方法

             services.AddHttpClient("github", c =>
            {
                //c.BaseAddress = new Uri("https://api.github.com/");
                c.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
                c.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample");
                
            }).ConfigurePrimaryHttpMessageHandler(() =>
            {
                return new HttpClientHandler()
                {
                    UseDefaultCredentials = true,
                    Credentials = new NetworkCredential("", ""),
                };
            });

您的控制器将如下所示

 private readonly IHttpClientFactory _httpClientFactory;

        public DataProController(IHttpClientFactory httpClientFactory)
        {
            _httpClientFactory = httpClientFactory;
        }

        [HttpGet]
        public async Task<ActionResult> Get()
        {            
            var client = _httpClientFactory.CreateClient("github");
            
            client.BaseAddress = new Uri("https://api.github.com/");

            string result = await client.GetStringAsync("/");
            return Ok(result);
        }

使用httpclientfactory时,您可能无法在运行时设置网络凭据,并且可能需要在启动类中进行设置。您可以在这里找到有关此问题的信息。 https://github.com/aspnet/HttpClientFactory/issues/71

答案 1 :(得分:0)

如果使用.net依赖注入,则可以将一个类的配置添加到安装代码中:

services
    .AddTransient<DataLoader>()
    .AddHttpClient<DataLoader>().ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler()
{
    Credentials = new NetworkCredential(LoadUsernameFromConfig(), LoadPasswordFromSecureLocation())
});

立即添加,DI将使用该凭据的HttpClient注入DataLoader类中:

    public class DataLoader
    {
        private readonly HttpClient httpClient;

        public DataLoader(HttpClient httpClient)
        {
            this.httpClient = httpClient;
        }

        public async Task LoadData(string tableName)
        {
            var json = await httpClient.GetStringAsync("https://protected.example.com/json");
            ...
        }
    }

(如果我没有Imran Arshad的回答,我将无法提供此代码:谢谢!)

答案 2 :(得分:0)

您可以这样创建身份验证委派处理程序:

public class AuthenticationHttpMessageHandler : DelegatingHandler
    {
        protected override async Task<HttpResponseMessage> SendAsync(
            HttpRequestMessage request,
            CancellationToken cancellationToken)
        {
            // Get the token or other type of credentials here
            // string scheme = ... // E.g. "Bearer", "Basic" etc.
            // string credentials = ... // E.g. formatted token, user/password etc.

            request.Headers.Authorization =
                new AuthenticationHeaderValue(scheme, credentials);

            return await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
        }
    }

然后将其添加到HttpClient构建器和DI容器中:

 services
     .AddTransient<AuthenticationHttpMessageHandler>()
     .AddHttpClient("MyClient")
     .AddHttpMessageHandler<AuthenticationHttpMessageHandler>();

然后使用IHttpClientFactory创建HttpClient实例。

此方法的核心优点是您可以清楚地分开关注点。您无需触摸主处理程序,也无需手动管理客户端创建,而是利用了工厂及其构建器扩展方法的全部功能。身份验证处理程序自然会注入到管道中,并向每个请求添加授权。通过抽象化凭据来源并使该处理程序依赖于IAuthenticationProvider抽象,可以进一步增强此处理程序,该方法仅需要DI配置,而无需使用HttpClient配置代码。