4
votes

We have need to utilize JWT tokens coming from IdentityServer4 typically, but also from Auth0 for more complex SSO scenarios to authorize access to an asp.net core 2.0 web api.

This code snippet from Startup.cs ConfigureServices tries to register Authentication handlers for both Auth0 and IdentityServer4 processing, but obviously fails with an InvalidOperationException: "Scheme already exists: Bearer"

        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        })
        .AddJwtBearer(options =>
        {
            options.Audience = Configuration["Auth0:ApiIdentifier"];
            options.Authority = $"https://{Configuration["Auth0:Domain"]}/";
        })
        .AddIdentityServerAuthentication(options =>
        {
            options.Authority = "http://localhost:5000";
            options.RequireHttpsMetadata = false;
            options.ApiName = "api1";
        });

How can this best be accomplished, I assume involving some type of separate handling based on the issuer in the token?

1
I think that’s coming from IdSrv. Did you try giving IdSrv a separate scheme name?Muqeet Khan

1 Answers

0
votes

It turns out that as Muqeet Khan hinted above, the schemes must be named differently, as shown below.

    services.AddAuthentication()
    .AddJwtBearer("Auth0", options =>
    {
        options.Audience = Configuration["Auth0:ApiIdentifier"];
        options.Authority = $"https://{Configuration["Auth0:Domain"]}/";
    })
    .AddIdentityServerAuthentication("IdSrv", options =>
    {
        options.Authority = "http://localhost:5000";
        options.RequireHttpsMetadata = false;
        options.ApiName = "api1";
    });

However, the default [Authorize] attribute only calls the default AuthenticationScheme. Rather than specifying both schemes for every Authorization, I registered them globally as so:

    services.AddMvcCore()
      .AddAuthorization()
      .AddJsonFormatters()
      .AddMvcOptions(options =>
      {
        var policy = new AuthorizationPolicyBuilder("IdSrv", "Auth0")
          .RequireAuthenticatedUser()
          .Build();
        options.Filters.Add(new AuthorizeFilter(policy));
      });