Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I have created a JWT Token Handler for my Web API project. The idea is that this API is merely a gateway to other APIs and a token is shared across them all. So when a call is made to my API and I am forwarding the call to another, I want to automatically forward the JWT that was attached to the initial request.

I made a custom MessageHandler as seen below:

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);
   } 
}

Then I registered it as a service in the Startup as below:

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>();

The application runs up until a request is made and then this exception comes up:

An unhandled exception has occurred while executing the request.

System.InvalidOperationException: No service for type 'Application.API1.JwtTokenHeaderHandler' has been registered. at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider) at Microsoft.Extensions.DependencyInjection.HttpClientBuilderExtensions.<>c__4`1.b__4_1(HttpMessageHandlerBuilder b) at Microsoft.Extensions.Http.DefaultHttpClientFactory.<>c__DisplayClass17_0.g__Configure|0(HttpMessageHandlerBuilder b) at Microsoft.Extensions.Http.LoggingHttpMessageHandlerBuilderFilter.<>c__DisplayClass3_0.b__0(HttpMessageHandlerBuilder builder)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
486 views
Welcome To Ask or Share your Answers For Others

1 Answer

First, injecting HttpContext directly will cause issues. Use IHttpContextAccessor and access the context in the Send method.

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);
    } 
}

Next GetRequiredService throws that exception when the requested service is not registered with the collection so make sure to register the handler with the container

Note

The handler type must be registered as a transient service.

Reference AddHttpMessageHandler<THandler>(IHttpClientBuilder)

services.AddTransient<JwtTokenHeaderHandler>();

So that JwtTokenHeaderHandler can be resolved when requested from the service provider

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...