13

Is there a way to handle JWTs from multiple issuers in single asp.net core 2.0 application?

Here how I'm currently checking tokens:

public void ConfigureServices(IServiceCollection services)
{
    TokenValidationParameters tokenValidationParameters = new TokenValidationParameters
    {
        // ...

        ValidateIssuer = true,
        ValidIssuer = options.Issuer, // <-- could this be a list of issuers?

        // ...
    };

    services.AddAuthentication()
        .AddJwtBearer(jwtOptions =>
        {
            jwtOptions.TokenValidationParameters = tokenValidationParameters;
        });

    services.AddAuthorization(authOptions =>
        {
            authOptions.DefaultPolicy = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme).RequireAuthenticatedUser().Build();
        });
}

public void Configure(IApplicationBuilder app)
{   
    // ...
    app.UseAuthentication();
}

The reason why I want to handle multiple issuers is because I need to handle different user types with different kind of permissions. To allow specific users only on some services in a microservice architecture environment I would like to issue tokens for each user type with a different issuer.

Mathias
  • 1,819
  • 4
  • 22
  • 34
  • See https://stackoverflow.com/questions/49694383/use-multiple-jwt-bearer-authentication for the solution we use in our application - calling AddJwtBearer multiple times. – Matt Varblow Jul 23 '18 at 00:05

2 Answers2

17

The simple answer would be to set the ValidIssuers property of the TokenValidationParameters instance instead of the ValidIssuer property. The ValidIssuers property takes an IEnumerable, so you can fill a list of issuer names and assign it to that property (or just inline the list).

var issuers = new List<string>()
    {
        "issuerA",
        "issuerB"
    };
// ...
TokenValidationParameters tokenValidationParameters = new TokenValidationParameters
{
    // ...

    ValidateIssuer = true,
    ValidIssuers = issuers

    // ...
};

Caveat: This assumes that each issuer shares the same secret (or list of secrets, if you use the corresponding IssuerSigningKeys property instead of the IssuerSigningKey property).

Jarod C
  • 186
  • 1
  • 4
  • 1
    Many thanks! Sometimes the answer is so obvious that you don't see it. – Mathias Oct 05 '17 at 05:07
  • How would one handle multiple issuer/secret pairs? – JasonX May 29 '18 at 12:27
  • @JasonX: I assume, you could use the IssuerSigningKeyResolver property to specify your own resolver, which can take the token's issuer into account. – Christoph Herold Jul 20 '18 at 20:06
  • 2
    If you have multiple issuer/secret pairs then you can just call AddJwtBearer multiple times. See https://stackoverflow.com/questions/49694383/use-multiple-jwt-bearer-authentication. – Matt Varblow Jul 23 '18 at 00:06
3

I found this link to be extremely useful.

https://learn.microsoft.com/en-us/aspnet/core/security/authorization/limitingidentitybyscheme?view=aspnetcore-6.0#use-multiple-authentication-schemes

    // Authentication
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            options.Audience = "https://localhost:5000/";
            options.Authority = "https://localhost:5000/identity/";
        })
        .AddJwtBearer("AzureAD", options =>
        {
            options.Audience = "https://localhost:5000/";
            options.Authority = "https://login.microsoftonline.com/eb971100-7f436/";
        });

// Authorization
builder.Services.AddAuthorization(options =>
{
    var defaultAuthorizationPolicyBuilder = new AuthorizationPolicyBuilder(
        JwtBearerDefaults.AuthenticationScheme,
        "AzureAD");
    defaultAuthorizationPolicyBuilder =
        defaultAuthorizationPolicyBuilder.RequireAuthenticatedUser();
    options.DefaultPolicy = defaultAuthorizationPolicyBuilder.Build();
});