访问服务器上的 HttpClientHandler.Credentials?
Posted
技术标签:
【中文标题】访问服务器上的 HttpClientHandler.Credentials?【英文标题】:Accessing HttpClientHandler.Credentials on the server? 【发布时间】:2021-11-25 19:56:05 【问题描述】:我正在尝试在 Web API 服务器和调用 API 的客户端上实现基本身份验证。
这就是我在客户端代码中配置 HttpClient
对象的方式(注意我是如何设置凭据的)。
services.AddHttpClient<TrackAndTraceClient>()
.ConfigureHttpClient(httpClient =>
httpClient.BaseAddress = new Uri(settings.BaseUrl);
httpClient.Timeout = TimeSpan.FromMinutes(5);
)
.ConfigurePrimaryHttpMessageHandler(serviceProvider =>
return new HttpClientHandler()
Credentials = new NetworkCredential(settings.Username, settings.Password),
;
);
但是,这会导致服务器端没有收到 Authorization 标头。
我的问题是,以这种方式设置凭据实际上有什么作用?这些凭据放在哪里?
是否可以编写我的服务器以处理以这种方式配置的凭据?
【问题讨论】:
【参考方案1】:您可以将 Authorization 标头添加到您的客户端代码中,如下所示:
services.AddHttpClient<TrackAndTraceClient>()
.ConfigureHttpClient(httpClient =>
httpClient.BaseAddress = new Uri(settings.BaseUrl);
httpClient.Timeout = TimeSpan.FromMinutes(5);
var authenticationBytes = Encoding.ASCII.GetBytes($"settings.Username:settings.Password");
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(authenticationBytes));
);
您可以使用AuthenticationHandler 来检查服务器端的Authorization 标头。下面是example 介绍如何使用 AuthenticationHandler 实现基本身份验证。
【讨论】:
我已经有了执行此操作的代码。我的问题是 1. 当我设置Credentials
属性时凭据放置在哪里,以及 2. 如何配置服务器以读取设置的凭据。【参考方案2】:
PreAuthenticate
应该发送身份验证标头。
services.AddHttpClient<TrackAndTraceClient>()
.ConfigureHttpClient(httpClient =>
httpClient.BaseAddress = new Uri(settings.BaseUrl);
httpClient.Timeout = TimeSpan.FromMinutes(5);
)
.ConfigurePrimaryHttpMessageHandler(serviceProvider =>
return new HttpClientHandler()
PreAuthenticate = true,
Credentials = new NetworkCredential(settings.Username,
settings.Password)
;
);
如果这不起作用,可能是由于HttpClientHandler
类中的Credentials
属性具有[UnsupportedOSPlatform("browser")]
属性(从.NET 5 开始)——注意PreAuthenticate
属性也是如此。此外,HttpClientHandler
类还包含如下定义:
.NET Framework 和 .NET Core 2.0 及更早版本中 HttpClient 使用的默认消息处理程序。
我看到你的帖子有标签.NET 6
,所以这也可能是导致它没有发送的一个因素。如果我是你,我会使用中间件从请求中接收身份验证标头,并使用 @Burhan Savci 发布的解决方案发送它。
假设您的后端是类似的 .NET Core API:
public class BasicAuthMiddleware
private readonly RequestDelegate _next;
public BasicAuthMiddleware(RequestDelegate next)
_next = next;
public async Task Invoke(HttpContext httpContext)
string authHeader =
httpContext.Request.Headers["Authorization"];
if (authHeader != null)
string auth = authHeader.Split(new char[] ' ' )[1];
Encoding encoding = Encoding.GetEncoding("UTF-8");
var usernameAndPassword =
encoding.GetString(Convert.FromBase64String(auth));
string username = usernameAndPassword
.Split(new char[] ':' )[0];
string password = usernameAndPassword
.Split(new char[] ':' )[1];
if (username == "abc" && password == "123")
await _next(httpContext);
else
httpContext.Response.StatusCode = 401;
return;
else
httpContext.Response.StatusCode = 401;
return;
然后在你的 Startup 类的 configure 方法中:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
app.UseMiddleware<BasicAuthMiddleware>();
【讨论】:
很抱歉延迟了实际尝试这个。首先,设置PreAuthenticate = true
不起作用。有趣的是,我正在使用完全相同的方法调用第三方 API,并且效果很好。但是当它调用我的 Web API 时,没有 Authorization 标头。我的 Web API 根据this article 实现基本身份验证。我很困惑为什么我需要额外的中间件。以上是关于访问服务器上的 HttpClientHandler.Credentials?的主要内容,如果未能解决你的问题,请参考以下文章
TestServer CreateClient 和 HttpClientHandler - 如何?
HttpClientHandler / 请求被中止:无法创建 SSL/TLS 安全通道
HttpClientHandler / HttpClient 内存泄漏