.NET 6中如何让HttpClient自动携带当前请求的JWT令牌
解决方案:利用自定义DelegatingHandler自动传递JWT
要实现HttpClient自动携带当前请求的JWT,最优雅的方式是使用自定义DelegatingHandler——它能拦截HttpClient的出站请求,从当前请求上下文里获取Authorization头,自动附加到调用用户微服务的请求中。
1. 注册IHttpContextAccessor
首先在Program.cs中注册IHttpContextAccessor,让我们能在Handler里获取当前请求的上下文:
builder.Services.AddHttpContextAccessor();
2. 创建自定义DelegatingHandler
新建一个继承DelegatingHandler的类(比如AuthorizationHeaderHandler),通过注入的IHttpContextAccessor拿到当前请求的Authorization头,再添加到出站请求里:
public class AuthorizationHeaderHandler : DelegatingHandler { private readonly IHttpContextAccessor _httpContextAccessor; public AuthorizationHeaderHandler(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; } protected override async Task<HttpResponseMessage> SendAsync( HttpRequestMessage request, CancellationToken cancellationToken) { var httpContext = _httpContextAccessor.HttpContext; if (httpContext != null && httpContext.Request.Headers.TryGetValue("Authorization", out var authHeader)) { // 直接将当前请求的Authorization头附加到出站请求 request.Headers.Add("Authorization", authHeader.ToString()); } return await base.SendAsync(request, cancellationToken); } }
3. 注册HttpClient时绑定自定义Handler
回到Program.cs,注册IUserClient时把自定义Handler加入HttpClient的处理链:
// 先注册自定义Handler builder.Services.AddTransient<AuthorizationHeaderHandler>(); builder.Services.AddHttpClient<IUserClient, UserClient>(client => { client.BaseAddress = new Uri(builder.Configuration["Clients:UserBaseUrl"]); }) .AddHttpMessageHandler<AuthorizationHeaderHandler>(); // 添加自定义Handler
4. 简化业务层调用逻辑
现在API层和业务层都不需要手动传递JWT参数了:
// API层代码(无需再传Authorization头) var createdOrder = await _orderService.Add(model.MapToDto()); // 业务层Add方法(无需接收JWT参数) public async Task<OrderDto> Add(OrderDto orderDto) { // 调用UserClient时,HttpClient会自动携带当前请求的JWT var userExists = await _userClient.CheckUserExists(orderDto.UserId); if (!userExists) { throw new Exception("用户不存在"); } // 其他订单创建逻辑... }
方案优势
- 符合洋葱架构职责分离:API层不用关心业务层调用外部服务的认证逻辑,业务层也无需手动传递认证信息
- 复用性强:所有使用该HttpClient的场景都会自动携带JWT,避免重复编码
- 解耦易维护:认证逻辑集中在Handler中,后续修改认证规则只需调整Handler即可
内容的提问来源于stack exchange,提问作者Artsiom Auhustsinovich
相关产品推荐
相关产品推荐

