C# 在运行时使用网络凭据更新HttpMessageHandler或创建类型化HttpClient
我需要根据使用应用程序的最终用户,在应用程序运行时传递网络凭据以模拟域用户。我还不知道如何通过Services.AddHttpClient和HttpClientFactory生成HttpClient,其中绑定到单个用户C# 在运行时使用网络凭据更新HttpMessageHandler或创建类型化HttpClient,c#,asp.net-core,.net-core,asp.net-core-mvc,C#,Asp.net Core,.net Core,Asp.net Core Mvc,我需要根据使用应用程序的最终用户,在应用程序运行时传递网络凭据以模拟域用户。我还不知道如何通过Services.AddHttpClient和HttpClientFactory生成HttpClient,其中绑定到单个用户 var httpClientBuilder = services .AddHttpClient<SomeHttpClint>() .ConfigurePrimaryHttpMessageHandler(s
var httpClientBuilder = services
.AddHttpClient<SomeHttpClint>()
.ConfigurePrimaryHttpMessageHandler(sp => new HttpClientHandler
{
AllowAutoRedirect = false,
UseCookies = false,
Credentials = new NetworkCredential("user", "pass", "domain")
});
var httpClientBuilder=services
.AddHttpClient()
.ConfigurePrimaryHttpMessageHandler(sp=>new HttpClientHandler
{
AllowAutoRedirect=false,
UseCookies=false,
凭据=新网络凭据(“用户”、“通过”、“域”)
});
因此,我的问题如下:
您可以在运行时注册客户端。这是我的变通代码。 定义2类:
public class DynamicHttpClientFactoryOptions : IConfigureNamedOptions<HttpClientFactoryOptions>
{
private readonly DynamicHttpClientFactoryWrapper _options;
public DynamicHttpClientFactoryOptions(DynamicHttpClientFactoryWrapper options)
{
_options = options;
}
public void Configure(HttpClientFactoryOptions options)
{
}
public void Configure(string name, HttpClientFactoryOptions options)
{
if (!_options.TryGetValue(name, out var configure)) return;
configure(options);
}
}
public class DynamicHttpClientFactoryWrapper : ConcurrentDictionary<string, Action<HttpClientFactoryOptions>>
{
public HttpClient GetOrCreateClient(string name, Action<HttpClientFactoryOptions> optionsBuilder)
{
if (!ContainsKey(name) || !TryGetValue(name, out var action))
{
TryAdd(name, optionsBuilder);
}
//you can store serviceProvider in startup class
var factory = _serviceProvider.GetRequiredService<IHttpClientFactory>();
return factory.CreateClient(name);
}
}
此代码为HttpClient配置依赖项注入。这意味着,如果您的控制器或可由DI创建的任何其他类型需要
SomeHttpClient
依赖项,它将从DI容器接收该依赖项。也可以要求指定客户。在最坏的情况下,您可以将工厂添加为DI依赖项,而不是为#2添加类型化的clienta,这实际上是在要求做DI已经做过的事情。那样你什么也得不到。显示如何将HttpClientFactory本身作为依赖项注入,并请求命名客户端。仅与命名客户端一起使用IHttpClientFactory
,无法解决此问题。您仍然需要在编译时注册命名的客户机。也许您可以使用委派处理程序@ChrisPratt我曾研究过委托处理程序,但根据我在源代码中看到的情况,我认为这是不可能的。凭据绑定到客户端处理程序,并且在初始化客户端后无法更改客户端处理程序。
services.AddHttpClient(...);
services.AddSingleton<DynamicHttpClientFactoryWrapper>();
services.ConfigureOptions<DynamicHttpClientFactoryOptions>();
public class SomeClass
{
private readonly DynamicHttpClientFactoryWrapper _wrapper;
public SomeClass(DynamicHttpClientFactoryWrapper wrapper)
{
_wrapper = wrapper;
}
public async Task Work()
{
var client = _wrapper.GetOrCreateClient(name/*userid or something else*/, options =>
{
options.HttpClientActions.Add(c =>
{
c.BaseAddress = new Uri("...");
});
options.HttpMessageHandlerBuilderActions.Add(handlerBuilder =>
{
var handler = new HttpClientHandler
{
Credentials = new NetworkCredential("user", "pass", "domain")
}
handlerBuilder.PrimaryHandler = handler;
});
});
var response = await client.SendAsync(request);
//do your work...
}
}