Estoy desarrollando la aplicación asp .net core web api 2.1.

Agrego el servicio de autenticación JWT como método de extensión en clase estática:

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

Que uso en el método ConfigureServices de la clase de inicio de esta manera:

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

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

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

Ahora, tengo el requisito de usar el patrón IOptions para obtener datos de autenticación JWT de appsettings.json

¿Cómo puedo obtener IOptions en el método ConfigureServices para pasar el emisor y la clave al método de extensión? ¿O cómo pasar IOptions al método de extensión?

8
Dmitry Stepanov 10 sep. 2018 a las 16:02

3 respuestas

La mejor respuesta

Para vincular datos de appsettings.json a Model, puede seguir los pasos a continuación:

  1. Contenido Appsettings.json

    {
    "Logging": {
     "IncludeScopes": false,
     "LogLevel": {
        "Default": "Warning"
           }
     },      
     "JWT": {
          "Issuer": "I",
          "Key": "K"
        }
     }
    
  2. Opciones de JWT

    public class JwtOptions
    {
        public string Issuer { get; set; }
        public string Key { get; set; }
     }
    
  3. Startup.cs

    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();
    }
    
  4. Una opción más para pasar JwtOptions directamente.

    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();
    }
    
  5. Cambiar el método de extensión.

    public static IServiceCollection AddJwtAuthentication(this IServiceCollection services, JwtOptions opt)
    
8
spottedmahn 9 oct. 2019 a las 15:53

Puede agregar sus opciones al contenedor DI en la clase de inicio de esta manera:

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

}

public void ConfigureService(IServiceCollection services)
{
    services.AddOptions();
    services.Configure<JwtOptions>(Configuration.GetSection("Jwt"));
}

Ahora puede usar estas opciones, en una etapa de configuración o en un método de extensión:

public void Configure(IApplicationBuilder app)
{
    var options = app.ApplicationServices.GetService<IOptions<JwtOptions>();
    // write your own code
}
1
Igor Goyda 10 sep. 2018 a las 13:28

Otra opción es vincular las configuraciones a una clase con la extensión Bind(). (OMI, esta es una solución más limpia que las 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)
{....}

Luego, si necesita la configuración de JwtKeys en otro lugar de la solución, simplemente registre la clase en la colección e inyéctela donde sea necesario

services.AddSingleton(jwtKeys);
5
spottedmahn 9 oct. 2019 a las 15:57