1

Is it possible to DI service in JwtSecurityTokenHandler?

I am following herostwist's answer to modify the JwtTokenAuthenicaiton in my code.

I have the following two, JwtSecurityTokenHandler and IPostConfigureOptions<JwtBearerOptions>:

public class CustomJwtBearerOptionsPostConfigureOptions
    : IPostConfigureOptions<JwtBearerOptions>
{
    private readonly RevokableJwtSecurityTokenHandler _revokableJwtSecurityTokenHandler;

    public CustomJwtBearerOptionsPostConfigureOptions(
        RevokableJwtSecurityTokenHandler revokableJwtSecurityTokenHandler)
    {
        _revokableJwtSecurityTokenHandler = revokableJwtSecurityTokenHandler;
    }

    public void PostConfigure(string name, JwtBearerOptions options)
    {
        options.SecurityTokenValidators.Clear();
        options.SecurityTokenValidators.Add(_revokableJwtSecurityTokenHandler);
    }
}

And:

public class RevokableJwtSecurityTokenHandler : JwtSecurityTokenHandler
{
    //this DI has issue
    private readyonly ApplicationDbContext _context;
    public RevokableJwtSecurityTokenHandler(ApplicationDbContext context)       
    {
        _context=context
    }
    public override ClaimsPrincipal ValidateToken(
        string token, TokenValidationParameters validationParameters,
        out SecurityToken validatedToken)
    {

        var claimsPrincipal =
            base.ValidateToken(token, validationParameters, out validatedToken);
        var claim = claimsPrincipal.FindFirst(JwtRegisteredClaimNames.Jti);
        if (claim?.ValueType == ClaimValueTypes.String)
        {
        }

        return claimsPrincipal;
    }
}

I have the following in Startup.cs. It works for Singleton when the JwtSecurityTokenHandler doesn't have any DI. I wanted to inject ApplicationDBContext from Entity Framework. I tried with Transient and somehow I still getting the " Cannot consume scoped service" error.

services.AddTransient<RevokableJwtSecurityTokenHandler>();
services.AddTransient<IPostConfigureOptions<JwtBearerOptions>,
CustomJwtBearerOptionsPostConfigureOptions>();

Error:

AggregateException: Some services are not able to be constructed Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler Lifetime: Transient ImplementationType: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler': Cannot consume scoped service 'TestAPI.Data.ApplicationDbContext' from singleton

Steven
  • 166,672
  • 24
  • 332
  • 435
Ray
  • 29
  • 1
  • 5
  • Tried It gives the same error. Cannot consume scoped service. I am start to wondering if I am doing some antipattern or things just doesn't logically work. – Ray May 19 '20 at 16:43
  • Related: https://stackoverflow.com/questions/50362622/net-core-scoped-called-in-singleton-through-di – Steven May 19 '20 at 19:38
  • The exception not that helpful, but it seems that the graph of objects that `ApplicationDbContext` belows to, is injected into a singleton component. Annoyingly enough, the error does not explain what this singleton component is. Try making that Singleton component Scoped. If that's not possible, you might want to manage your scope manually, as described [here](https://thinkrethink.net/2018/07/12/injecting-a-scoped-service-into-ihostedservice/). – Steven May 19 '20 at 19:40
  • i think the singleton the errror to is this: [Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions]]' from singleton 'Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions]'.)'. Do I have to implement custom JWTBearOptions? – Ray May 20 '20 at 00:52

0 Answers0