共享 ASP.NET Core 3.1 启动和控制器中使用的配置对象的最佳方式是什么

Way*_*yne 1 c# asp.net-core asp.net-core-configuration

在 ASP.NET Core 3.1 启动类和控制器之间共享配置对象的最佳方式是什么?

我看过一些使用 DI 的例子,这看起来是个好主意,但我需要在public void ConfigureServices(IServiceCollection services).

此外,对象依赖于一个Microsoft.Extensions.Configuration.IConfiguration实例。

该对象将在 内Startup.csConfigureServices自身内以及在 内使用Controllers

DI 会工作吗?或者解决方案是带参数的单例?

下面是需要分享的具体代码:

// openssl rand -hex 16 => 256 bits when read
var jwt_key = Configuration.GetSection("JwtOption:IssuerSigningKey").Value;
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwt_key));

var tokenValidationParameters = new TokenValidationParameters
{
    // The signing key must match!
    ValidateIssuerSigningKey = true,
    IssuerSigningKey = signingKey,

    // Validate the JWT Issuer (iss) claim
    ValidateIssuer = true,
    ValidIssuer = "some host name",

    // Validate the JWT Audience (aud) claim
    ValidateAudience = true,
    ValidAudience = "web_intranet",

    // Validate the token expiry
    ValidateLifetime = true,

    // If you want to allow a certain amount of clock drift, set that here:
    ClockSkew = TimeSpan.Zero
};
Run Code Online (Sandbox Code Playgroud)

该对象在public void ConfigureServices(IServiceCollection services)方法中的使用如下

services
    .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {                
        options.TicketDataFormat = new CustomJwtDataFormat(
            SecurityAlgorithms.HmacSha256,
            tokenValidationParameters);
    });
Run Code Online (Sandbox Code Playgroud)

Nko*_*osi 5

尽量避免传递 IConfiguration。共享代码可以在 Startup 中完成,模型填充并添加到容器中

您可以直接在容器中注册实例 Startup.ConfigureServices

void ConfigureServices(IServiceCollection services) {
    var jwt_key = Configuration.GetSection("JwtOption:IssuerSigningKey").Value;
    var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwt_key));

    var tokenValidationParameters = new TokenValidationParameters {
        //...code omitted for brevity
    }

    services.AddSingleton(tokenValidationParameters);

    //...can still use tokenValidationParameters

    services
        .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie(options =>
        {                
            options.TicketDataFormat = new CustomJwtDataFormat(
                SecurityAlgorithms.HmacSha256,
                tokenValidationParameters);
        });
}
Run Code Online (Sandbox Code Playgroud)

并在需要的地方显式注入

//ctr
public MyController(TokenValidationParameters tokenParameters) {

    //...

}
Run Code Online (Sandbox Code Playgroud)

或者您可以使用选项模式

ASP.NET Core 中的参考选项模式

void ConfigureServices(IServiceCollection services) {
    //...code omitted for brevity
    var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwt_key));

    services.Configure<TokenValidationParameters>(options => {    
        // The signing key must match!
        options.ValidateIssuerSigningKey = true;
        options.IssuerSigningKey = signingKey;

        // Validate the JWT Issuer (iss) claim
        options.ValidateIssuer = true;
        options.ValidIssuer = "some host name";

        // Validate the JWT Audience (aud) claim
        options.ValidateAudience = true;
        options.ValidAudience = "web_intranet";

        // Validate the token expiry
        options.ValidateLifetime = true;

        // If you want to allow a certain amount of clock drift, set that here:
        options.ClockSkew = TimeSpan.Zero;
    });

    //...

    //Use DI services to configure cookie options
    var scheme = CookieAuthenticationDefaults.AuthenticationScheme;
    services.AddOptions<CookieAuthenticationOptions>(scheme)
        .Configure<IOptions<TokenValidationParameters>>((options, token) => {
            options.TicketDataFormat = new CustomJwtDataFormat(
                SecurityAlgorithms.HmacSha256,
                token.Value); //<--
        });

    services
        .AddAuthentication(scheme)
        .AddCookie();
}
Run Code Online (Sandbox Code Playgroud)

参考使用 DI 服务配置选项

IOptions<TokenValidationParameters>在需要的地方注入

//ctr
public MyController(IOptions<TokenValidationParameters> options) {

    TokenValidationParameters tokenParameters = options.Value;

    //...

}
Run Code Online (Sandbox Code Playgroud)