如何在ConfigureServices方法中获取IOptions或将IOptions传递给扩展方法?

Dmi*_*nov 7 asp.net-web-api .net-core asp.net-core asp.net-core-2.0

我正在开发ASP .NET Core Web API 2.1应用程序。

我将JWT身份验证服务添加为静态类中的扩展方法:

 public static class AuthenticationMiddleware
    {
        public static IServiceCollection AddJwtAuthentication(this IServiceCollection services, string issuer, string key)
        {
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options =>
                {
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        // validate the server that created that token
                        ValidateIssuer = true,
                        // ensure that the recipient of the token is authorized to receive it
                        ValidateAudience = true,
                        // check that the token is not expired and that the signing key of the issuer is valid
                        ValidateLifetime = true,
                        // verify that the key used to sign the incoming token is part of a list of trusted keys
                        ValidateIssuerSigningKey = true,
                        ValidIssuer = issuer,
                        ValidAudience = issuer,
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key))
                    };
                });

            return services;
        }
    }
Run Code Online (Sandbox Code Playgroud)

我在Startup类的ConfigureServices方法中使用的是这样的:

public void ConfigureServices(IServiceCollection services)
        {
            // adding some services here

            services.AddJwtAuthentication(Configuration["Jwt:Issuer"], Configuration["Jwt:Key"]);

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);           
        }
Run Code Online (Sandbox Code Playgroud)

现在,我需要使用IOptions模式从appsettings.json获取JWT身份验证数据

如何在ConfigureServices方法中获取IOptions以将颁发者和密钥传递给扩展方法?或者如何将IOptions传递给扩展方法?

Tao*_*hou 9

appsettings.json要将数据从绑定到Model,您可以按照以下步骤操作:

  1. Appsettings.json内容

    {
    "Logging": {
     "IncludeScopes": false,
     "LogLevel": {
        "Default": "Warning"
           }
     },      
     "JWT": {
          "Issuer": "I",
          "Key": "K"
        }
     }
    
    Run Code Online (Sandbox Code Playgroud)
  2. JWT选项

    public class JwtOptions
    {
        public string Issuer { get; set; }
        public string Key { get; set; }
     }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 启动文件

    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<JwtOptions>(Configuration.GetSection("JWT"));
        var serviceProvider = services.BuildServiceProvider();
        var opt = serviceProvider.GetRequiredService<IOptions<JwtOptions>>().Value;
        services.AddJwtAuthentication(opt.Issuer, opt.Key);
        services.AddMvc();
    }
    
    Run Code Online (Sandbox Code Playgroud)
  4. JwtOptions直接传递的另一种选择。

    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<JwtOptions>(Configuration.GetSection("JWT"));
        var serviceProvider = services.BuildServiceProvider();
        var opt = serviceProvider.GetRequiredService<IOptions<JwtOptions>>().Value;
        services.AddJwtAuthentication(opt);
    
        services.AddMvc();
    }
    
    Run Code Online (Sandbox Code Playgroud)
  5. 更改扩展方式。

    public static IServiceCollection AddJwtAuthentication(this IServiceCollection services, JwtOptions opt)
    
    Run Code Online (Sandbox Code Playgroud)


Mar*_*und 6

另一种选择是将配置绑定到具有Bind()扩展名的类。(IMO 这是一个比 IOptions 更干净的解决方案)

public class JwtKeys
{
    public string Issuer { get; set; }
    public string Key { get; set; }
}

public void ConfigureServices(IServiceCollection services)
{
    var jwtKeys = new JwtKeys();
    Configuration.GetSection("JWT").Bind(JwtKeys);

    services.AddJwtAuthentication(jwtKeys);
}

public static IServiceCollection AddJwtAuthentication(this IServiceCollection services, JwtKeys jwtKeys)
{....}
Run Code Online (Sandbox Code Playgroud)

然后,如果您需要解决方案中其他地方的 JwtKeys 设置,只需在集合上注册该类并在需要的地方注入它

services.AddSingleton(jwtKeys);
Run Code Online (Sandbox Code Playgroud)