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