Search code examples
c#jwtidentityserver4roles

Identity Server 4 - Role policy not workink


I have a problem catching a user role from a JWT token in my API. I added a role to my token and added a policy with the required role, but it's not working as I expected. Every time when I have respon status 403 Forbidden. IdentityServer site:

new IdentityResource[]
{
     new IdentityResources.OpenId(),
     new IdentityResources.Profile(),
     new IdentityResource(
         name: "user",
         userClaims: new[] {JwtClaimTypes.Email}),
     new IdentityResource(
         name: "role",
         userClaims: new[] {JwtClaimTypes.Role})
};
new Client()
{
    ClientId = "swagger",
    ClientName = "Client for Swagger use",
    
    AllowedGrantTypes = GrantTypes.CodeAndClientCredentials,
    ClientSecrets = {new Secret("secret".Sha256())},
    AllowedScopes = {"api1", "user", "openid", "role"},
    AlwaysSendClientClaims = true,
    AlwaysIncludeUserClaimsInIdToken = true,
    AllowAccessTokensViaBrowser = true,
    RedirectUris = {"https://localhost:44376/swagger/oauth2-redirect.html"},
    AllowedCorsOrigins = {"https://localhost:44376"}
}

API site:

services.AddAuthorization(optionns =>
{
    optionns.AddPolicy("admin", policy =>
    {
        policy.RequireAuthenticatedUser();
        policy.RequireClaim("scope", "api1");
        policy.RequireRole("admin");
    });
    optionns.AddPolicy("ApiScope", policy =>
    {
        policy.RequireAuthenticatedUser();
        policy.RequireClaim("scope", "api1");
    });
});

Controller site:

[Authorize(Policy = "admin")]

or

[Authorize(Role= "admin")]

My data from JWT token:

{
  "nbf": 1670283035,
  "exp": 1670286635,
  "iss": "https://localhost:5001",
  "aud": "https://localhost:5001/resources",
  "client_id": "swagger",
  "sub": "1",
  "auth_time": 1670282526,
  "idp": "local",
  "Email": "[email protected]",
  "role": "admin",
  "jti": "D07527BB11C8C4EEFC7A5012ADB38DE9",
  "sid": "97828B78D66B3A2C96CAE60F7F1A6D25",
  "iat": 1670283035,
  "scope": [
    "api1",
    "user",
    "openid",
    "role"
  ],
  "amr": [
    "pwd"
  ]
}

Any ideas to resolve this problem? I have already processed hundreds of problems on forums and tutorials and nothing has helped.


Solution

  • Microsoft and OpenID-Connect have different opinions on what the claims should be called.

    So, what you need to do in AddOpenIDConnect is to tell ASP.NET Core what the name of the role claim is, typically by adding something like:

    options.TokenValidationParameters = new TokenValidationParameters
    {
        NameClaimType = JwtClaimTypes.Name,
        RoleClaimType = JwtClaimTypes.Role
    };
    

    The best way to troubleshoot these problems is to look what is actually inside your ClaimsPrincipal User object. It might not always contains the claim you think it should contain.

    For more details, see this blog post https://leastprivilege.com/2017/11/15/missing-claims-in-the-asp-net-core-2-openid-connect-handler/

    To complement this answer, I wrote a blog post that goes into more detail about this topic: Debugging OpenID Connect claim problems in ASP.NET Core