你可以使用一个服务来配置另一个服务的方法是什么?

huangapple go评论102阅读模式
英文:

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&lt;JWTService&gt;();

builder.Services.AddAuthorization(options =&gt;
{   
    options.AddPolicy(&quot;UserPolicy&quot;, p =&gt; p.RequireAuthenticatedUser().RequireClaim(&quot;Profession&quot;));
});
builder.Services.AddAuthentication(x =&gt;
{
    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =&gt;
{
    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[&quot;JwtBearerTokenSettings:Audience&quot;],
            ValidIssuer = _configuration[&quot;JwtBearerTokenSettings:Issuer&quot;],
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration[&quot;JwtBearerTokenSettings:SecretKey&quot;]))
        };
    }
}

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 =&gt;
{
    options.AddPolicy(&quot;UserPolicy&quot;, p =&gt; p.RequireAuthenticatedUser().RequireClaim(&quot;Profession&quot;));
});
builder.Services.AddAuthentication(x =&gt;
{
    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer();

builder.Services
    .AddOptions&lt;JwtBearerOptions&gt;(JwtBearerDefaults.AuthenticationScheme)
    .Configure&lt;IConfiguration&gt;((options, configuration) =&gt;
    {
        options.TokenValidationParameters = new TokenValidationParameters()
        {
            ValidateActor = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ClockSkew = TimeSpan.Zero,
            ValidAudience = configuration[&quot;JwtBearerTokenSettings:Audience&quot;],
            ValidIssuer = configuration[&quot;JwtBearerTokenSettings:Issuer&quot;],
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration[&quot;JwtBearerTokenSettings:SecretKey&quot;])),
        };
    });

huangapple
  • 本文由 发表于 2023年8月8日 23:02:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/76860825.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定