英文:
How can I use a service to configure another service?
问题
你可以使用依赖注入来获取JWTService
的实例,并将其作为AddJwtBearer
方法的参数。不建议使用builder.Services.BuildServiceProvider().GetServices
的方式。
首先,你需要在Startup.cs
文件中注册JWTService
服务。在ConfigureServices
方法中添加以下代码:
builder.Services.AddSingleton<JWTService>();
然后,在AddJwtBearer
方法中,可以通过构造函数注入JWTService
实例,并调用其Config
方法来获取TokenValidationParameters
。修改代码如下:
builder.Services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
var jwtService = builder.Services.BuildServiceProvider().GetRequiredService<JWTService>();
options.TokenValidationParameters = jwtService.Config();
});
这样,你就可以通过依赖注入的方式获取JWTService
实例,并使用其Config
方法来设置TokenValidationParameters
。这种方式更加推荐,避免了使用BuildServiceProvider().GetServices
的方式。
英文:
I'm configurating a AuthenticationService in my application, with JwtBearer .
I abstracted the JWT configuration to a service, to use it throughout the application. So, that's my code.
builder.Services.AddSingleton<JWTService>();
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("UserPolicy", p => p.RequireAuthenticatedUser().RequireClaim("Profession"));
});
builder.Services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.TokenValidationParameters = ...;
});
public class JWTService
{
private IConfiguration _configuration;
public JWTService(IConfiguration configuration)
{
_configuration = configuration;
}
public TokenValidationParameters Config()
{
return new TokenValidationParameters()
{
ValidateActor = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ClockSkew = TimeSpan.Zero,
ValidAudience = _configuration["JwtBearerTokenSettings:Audience"],
ValidIssuer = _configuration["JwtBearerTokenSettings:Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JwtBearerTokenSettings:SecretKey"]))
};
}
}
So, how can I get the JWTService to use it as a parameter of AddJwtBearer, with Config method?
I managed to do this using builder.Services.BuildServiceProvider().GetServices, but I read that this is not recommended.
Is there another way?
答案1
得分: 1
您应该能够添加一个委托,当服务被解析时将调用该委托,该委托还可以拥有其他您需要的服务,比如IConfiguration
,以便在使用之前动态配置选项:
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("UserPolicy", p => p.RequireAuthenticatedUser().RequireClaim("Profession"));
});
builder.Services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer();
builder.Services
.AddOptions<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme)
.Configure<IConfiguration>((options, configuration) =>
{
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateActor = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ClockSkew = TimeSpan.Zero,
ValidAudience = configuration["JwtBearerTokenSettings:Audience"],
ValidIssuer = configuration["JwtBearerTokenSettings:Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["JwtBearerTokenSettings:SecretKey"])),
};
});
英文:
You should be able to add a delegate which will be called when the service is resolved which can then also have other services you need, like IConfiguration
provided to it so that you can dynamically configure the options before they are used:
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("UserPolicy", p => p.RequireAuthenticatedUser().RequireClaim("Profession"));
});
builder.Services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer();
builder.Services
.AddOptions<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme)
.Configure<IConfiguration>((options, configuration) =>
{
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateActor = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ClockSkew = TimeSpan.Zero,
ValidAudience = configuration["JwtBearerTokenSettings:Audience"],
ValidIssuer = configuration["JwtBearerTokenSettings:Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["JwtBearerTokenSettings:SecretKey"])),
};
});
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论