JwtBearerOptions Configure method not getting executed

Viewed 244

I have asp.net core 3.1 web api project with the following code :

Startup.cs

public virtual void ConfigureServices(IServiceCollection services) =>
    services
    .AddFrameworkServices()
    .AddApplicationInsights(this.configuration)
    .AddResponseCompression()
    .AddCustomConfigureOptions();

CustomServiceCollectionExtensions.cs

public static IServiceCollection AddCustomConfigureOptions(this IServiceCollection services) =>
  services
    .ConfigureOptions<ConfigureAuthenticationOptions>();
    .ConfigureOptions<ConfigureJwtBearerOptions>();

ConfigureAuthenticationOptions.cs

public class ConfigureAuthenticationOptions : IConfigureOptions<AuthenticationOptions>
{
   public void Configure(AuthenticationOptions options) =>
      options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}

ConfigureJwtBearerOptions

public class ConfigureJwtBearerOptions : IConfigureOptions<JwtBearerOptions>
{
    private readonly IConfiguration configuration;
    public ConfigureJwtBearerOptions(IConfiguration configuration) => this.configuration = configuration;
    public void Configure(JwtBearerOptions options)
    {
        options.Authority = configuration[C.AppKeys.AADInstance] + configuration[C.AppKeys.AADTenantID];
        options.Audience = configuration[C.AppKeys.AADAudience];
    }
}

On debugging I found that Configure method of ConfigureJwtBearerOptions.cs file is not getting triggered

Can anyone help me with their guidance to fix this issue

2 Answers

I'm using .Net Core 6 and struggle with that same error. The subtility here is that .AddJwtBearer() use a named options delegate.

Instead of implementing IConfigureOptions, implement IConfigureNamedOptions

ConfigureJwtBearerOptions.cs

public class ConfigureJwtBearerOptions : IConfigureNamedOptions<JwtBearerOptions>
{
    private readonly JwtOptions config;
    private readonly ILogger<ConfigureJwtBearerOptions> logger;
   
    /// <summary>
    /// Configure JWT auth
    /// </summary>
    /// <param name="jwtOptions"></param>
    /// <param name="logger"></param>
    public ConfigureJwtBearerOptions(JwtOptions jwtOptions, ILogger<ConfigureJwtBearerOptions> logger)
    {
        config = jwtOptions;
        this.logger = logger;
    }

    /// <inheritdoc/>
    public void Configure(JwtBearerOptions options)
    {
        Configure(JwtBearerDefaults.AuthenticationScheme, options);
    }

    public void Configure(string name, JwtBearerOptions options)
    {
        options.Authority = config.Authority;
        options.Audience = config.Audience;

        logger.LogInformation("OAuth authority: {0}", config.Authority);
        logger.LogInformation("OAuth audience: {0}", config.Audience);
        //...
    }
}

Also, you still need to call AddAuthentication() in Startup.cs

Startup.cs

//...
services.AddAuthentication().AddJwtBearer();

I have been researching .NET authentication and Authorization and found that over the last year this landscape seemed to evolve pretty rapidly.

In the latestest documentationn I found Microsoft recommends different auth libraries for different auth types here: https://docs.microsoft.com/en-us/azure/active-directory/develop/reference-v2-libraries

In our latest .net 6 web API's are using Microsoft.Identity.Web and using services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(azureConfiguration, "AzureAd"); to add our authentication. We previously used .AddAuthentication().AddJwtBearer(options => {...})

I am currently learning this new auth library myself here: https://docs.microsoft.com/en-us/azure/active-directory/develop/scenario-protected-web-api-app-configuration#customizing-token-validation

Hope this was helpful!

Related