Search code examples
identityserver4roles

Co-hosting Identity Server 4 with API services using Roles


I've come across an example of co-hosting Identity Server 4 on the same App Host as the API Services that need it for authentication and authorization.

Now I was able to replicate this successfully by just pure authentication but when it comes to authorization using Roles I couldn't get it to work, i.e. adding the [Authorize(Roles = "My Role")] attribute on my Controller Action. The access token contains the "role" scope and claim but it doesn't seem to be respected at all.

I initially tried the code below but it doesn't execute the JWT Bearer bit at all which leads me to believe that Identity Server uses its own handler for that purpose and I have no idea how to configure it if at all.

services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    // JWT tokens (default scheme)
    .AddJwtBearer(options =>
    {
        options.Authority = "https://localhost:44367/";
        options.Audience = "API";

        options.TokenValidationParameters.RoleClaimType = "role";
    });

Then I came across this line from the example code (I mentioned initially in this post) which seems like its supposed to grant me the ability to run API services along side with Identity Server:

services.AddLocalApiAuthentication();

But it also doesn't seem to do what I want.

So does the Identity Server authentication middleware allow me to accomplish role-based authentication or is there some other mechanism (i.e. Policies) that I need to look into?

Something worth noting, I was able to accomplish all of this successfully with Identity Server 4 but by hosting it all separately. I want to see what it takes to host it all together.


Solution

  • Just rechecked the example and it worked perfectly fine.

    When you use

    services.AddLocalApiAuthentication();
    

    it sets up the IdentityServerAccessToken authenticationScheme.

    To use it in your API controller you type

    [Authorize(IdentityServerConstants.LocalApi.PolicyName)]
    

    as described in the doc, or just

    [Authorize(AuthenticationSchemes = "IdentityServerAccessToken")]
    

    All you need to check the roles is one more argument for the attribute:

    [Authorize(AuthenticationSchemes = "IdentityServerAccessToken", Roles = "test role1")]