ASP.NET Core Web API - JWT 消息处理程序 - 没有注册类型错误

Posted

技术标签:

【中文标题】ASP.NET Core Web API - JWT 消息处理程序 - 没有注册类型错误【英文标题】:ASP.NET Core Web API - JWT Message Handler - No Registered Type Error 【发布时间】:2021-04-14 05:24:42 【问题描述】:

我为我的 Web API 项目创建了一个 JWT 令牌处理程序。这个想法是这个 API 只是一个通往其他 API 的网关,并且一个令牌在它们之间共享。因此,当调用我的 API 并将调用转发给另一个时,我想自动转发附加到初始请求的 JWT。

我制作了一个自定义 MessageHandler,如下所示:

public class JwtTokenHeaderHandler : DelegatingHandler

    private readonly HttpContext httpContext;
   public JwtTokenHeaderHandler(HttpContext httpContext)
   
       this.httpContext = httpContext;
   
   protected override async Task<HttpResponseMessage> SendAsync(
       HttpRequestMessage request,
       CancellationToken cancellationToken)
   
       string savedToken = await this.httpContext.GetTokenAsync("access_token");
       request.Headers.Add("bearer", savedToken);
       return await base.SendAsync(request, cancellationToken);
    

然后我在 Startup 中将其注册为服务,如下所示:

services.AddTransient<HttpMessageHandler>(p => p.GetRequiredService<JwtTokenHeaderHandler>());

IHttpClientBuilder serviceClientBuilder = services.AddHttpClient<IService, Service>(client =>

    client.BaseAddress = new Uri(this.Configuration.GetValue<string>("ServiceURL"));
).AddHttpMessageHandler<JwtTokenHeaderHandler>();

应用程序一直运行,直到发出请求,然后出现此异常:

执行请求时发生未处理的异常。

System.InvalidOperationException:未注册“Application.API1.JwtTokenHeaderHandler”类型的服务。 在 Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider 提供程序,类型 serviceType) 在 Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider 提供程序) 在 Microsoft.Extensions.DependencyInjection.HttpClientBuilderExtensions.c__4`1.b__4_1(HttpMessageHandlerBuilder b) 在 Microsoft.Extensions.Http.DefaultHttpClientFactory.c__DisplayClass17_0.g__Configure|0(HttpMessageHandlerBuilder b) 在 Microsoft.Extensions.Http.LoggingHttpMessageHandlerBuilderFilter.c__DisplayClass3_0.b__0(HttpMessageHandlerBuilder 构建器)

【问题讨论】:

【参考方案1】:

首先,直接注入HttpContext 会导致问题。使用 IHttpContextAccessor 并在 Send 方法中访问上下文。

public class JwtTokenHeaderHandler : DelegatingHandler 
    private readonly IHttpContextAccessor accessor;

    public JwtTokenHeaderHandler(IHttpContextAccessor accessor) 
        this.accessor = accessor;
    

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
        string savedToken = await accessor.HttpContext.GetTokenAsync("access_token");
        request.Headers.Add("bearer", savedToken);
        return await base.SendAsync(request, cancellationToken);
     

下一个GetRequiredService 在请求的服务未向集合注册时抛出该异常,因此请确保向容器注册处理程序

注意

处理程序类型必须注册为临时服务。

参考AddHttpMessageHandler&lt;THandler&gt;(IHttpClientBuilder)

services.AddTransient<JwtTokenHeaderHandler>();

这样JwtTokenHeaderHandler可以在服务提供商请求时解析

services.AddTransient<HttpMessageHandler>(p => p.GetRequiredService<JwtTokenHeaderHandler>());
services.AddHttpClient<IService, Service>(client => 
    client.BaseAddress = new Uri(this.Configuration.GetValue<string>("ServiceURL"));
).AddHttpMessageHandler<JwtTokenHeaderHandler>();

【讨论】:

以上是关于ASP.NET Core Web API - JWT 消息处理程序 - 没有注册类型错误的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core Web API

Asp.Net Core 1.1 消费web api

使用 ASP.NET Core MVC 创建 Web API

如何从 ASP.NET MVC 到 ASP.NET Core Web API 的 PUT?

ASP.NET Web API 与 ASP.NET Core 中的 URL 匹配差异

使用 ASP.NET Core MVC 创建 Web API