Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get IOptions in ConfigureServices method or pass IOptions into extension method?

I'm developing asp .net core web api 2.1 app.

I add JWT authentication service as an extension method in static class:

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

which I use in ConfigureServices method of Startup class like this:

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

Now, I have a requirement to use IOptions pattern to get JWT authentication data from appsettings.json

How can I get IOptions in ConfigureServices method to pass issuer and key into extension method? Or how to pass IOptions to extension method?

like image 774
Dmitry Stepanov Avatar asked Sep 10 '18 13:09

Dmitry Stepanov


2 Answers

You can add your options to DI container in Startup class like this:

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

Now you can use this options, in a configure stage, or in an extension method:

public void Configure(IApplicationBuilder app)
{
    var options = app.ApplicationServices.GetService<IOptions<JwtOptions>();
    // write your own code
}
like image 51
Igor Goyda Avatar answered Oct 27 '22 00:10

Igor Goyda


One other option is to bind the configurations to a class with the Bind() extension. (IMO this a more clean solution then the 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)
{....}

Then if you need the JwtKeys settings some other place in the solution, just register the class on the collection and inject it where needed

services.AddSingleton(jwtKeys);
like image 43
Marcus Höglund Avatar answered Oct 26 '22 23:10

Marcus Höglund