Home > database >  ASP.NET Core Inject my service to JwtBearer
ASP.NET Core Inject my service to JwtBearer

Time:09-11

I'm trying to use my RsaSecurityKey service in conifugureOptions action parameter of extension method AddJwtBearer.

Extensions.cs

public static class Extensions
{
    public static IServiceCollection AddRsaSecurityKey(this IServiceCollection services, string publicKey)
    {
        services.AddSingleton(_ =>
        {
            var rsa = RSA.Create();
            rsa.ImportRSAPublicKey(
                source: Convert.FromBase64String(publicKey),
                bytesRead: out var _
            );

            return new RsaSecurityKey(rsa);
        });

        return services;
    }
}

Program.cs

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRsaSecurityKey(
    builder.Configuration.GetValue<string>("Jwt:Asymmetric:PublicKey")
);

builder.Services.AddAuthentication().AddJwtBearer("Asymmetric", options =>
{
    var rsa = builder.Services.BuildServiceProvider().GetRequiredService<RsaSecurityKey>();

    options.IncludeErrorDetails = true;
    options.RequireHttpsMetadata = false;
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidIssuer = "Server",
        ValidAudience = "Client",
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidAlgorithms = new[] {"RS256"},
        IssuerSigningKey = rsa,
        RequireSignedTokens = true,
        RequireExpirationTime = true
    };
});

...

I'm stacked at this line: var rsa = builder.Services.BuildServiceProvider().GetRequiredService<RsaSecurityKey>();

As I know, this would build a copy of IServiceProvider and get my service from it.

So the question is - How can I use my service properly inside options lambda?

CodePudding user response:

Remove the AddRsaSecurityKey method completely and change the registration of the JWT Bearer to the following:

builder.Services.AddAuthentication().AddJwtBearer("Asymmetric", options =>
{
    // Just create the RSA object here; no need to register it
    var rsa = RSA.Create();
    rsa.ImportRSAPublicKey(
        source: Convert.FromBase64String(
            builder.Configuration.GetValue<string>("Jwt:Asymmetric:PublicKey")),
        bytesRead: out var _
    );
    
    options.IncludeErrorDetails = true;
    options.RequireHttpsMetadata = false;
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidIssuer = "Server",
        ValidAudience = "Client",
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidAlgorithms = new[] {"RS256"},
        IssuerSigningKey = RsaSecurityKey(rsa), // supply it here
        RequireSignedTokens = true,
        RequireExpirationTime = true
    };
});
  • Related