'ASP.NET Identity Role claims missing

I'm logging in via Google using Duende IdentityServer, which is also configured to use ASP.NET Identity for user roles etc.

Google IdentityServer Config:

            .AddGoogle(options =>
            {
                options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
                options.ClientId = "redacted"
                options.ClientSecret = "redacted";

            });

Blazor UI Auth config:

builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})

    .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme,
        options =>
        {
            options.Authority = "myidentityserverurl";

            options.ClientId = "web2";
            options.ClientSecret = "secret";
            options.UsePkce = true;
            options.ResponseType = "code";            
            options.Scope.Add("api1");
            options.Scope.Add("roles");
            options.ClaimActions.MapUniqueJsonKey("role", "role");
            options.ClaimActions.MapUniqueJsonKey("roles", "role");

            options.TokenValidationParameters = new TokenValidationParameters
            {
                RoleClaimType = JwtClaimTypes.Role,
                ValidateAudience = false
            };
            options.SaveTokens = true;
            options.GetClaimsFromUserInfoEndpoint = true;
        });

API auth config:

builder.Services.AddAuthentication("Bearer")
    .AddJwtBearer(options =>
    {        
        options.Authority = "myidentityserverurl";
        options.Audience = "api1";

        options.TokenValidationParameters = new TokenValidationParameters
        {
            RoleClaimType = JwtClaimTypes.Role,
            ValidateAudience = false
        };
    });

I have a Blazor UI client which can successfully login via Google, which gives me back a Cookie, an access_token and an id_token.

The access_token returned from a Google login does not have any role claims from ASP.NET Identity, either from within Blazor or from Postman.

If I call /connect/userinfo in IdentityServer after logging in via google, I get the role I'm in as expected:

{
    "sub": "subhere",
    "name": "myname",
    "role": "SystemAdministrator",
    "preferred_username": "uuid from google"
}

In the Blazor app, if I get the claims from httpContextAccessor.HttpContext.User.Claims I get my role claim as expected.

If I make a call to my API using the access token issued as part of the login to the UI, and get the claims like so:

    public IActionResult Get()
    {
        return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
    }

I don't have any role claim at all here. And likewise no role claim in the bearer token in Postman after logging in via Google.

Here are the claims from the API, missing my role claim:

[
  {
    "type": "iss",
    "value": "myidentityserverurl"
  },
  {
    "type": "nbf",
    "value": "1653401427"
  },
  {
    "type": "iat",
    "value": "1653401427"
  },
  {
    "type": "exp",
    "value": "1653405027"
  },
  {
    "type": "aud",
    "value": "https://myidentityserverurl/resources"
  },
  {
    "type": "scope",
    "value": "openid"
  },
  {
    "type": "scope",
    "value": "profile"
  },
  {
    "type": "scope",
    "value": "api1"
  },
  {
    "type": "scope",
    "value": "roles"
  },
  {
    "type": "http://schemas.microsoft.com/claims/authnmethodsreferences",
    "value": "external"
  },
  {
    "type": "client_id",
    "value": "web2"
  },
  {
    "type": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",
    "value": "uuidhere"
  },
  {
    "type": "auth_time",
    "value": "1653401425"
  },
  {
    "type": "http://schemas.microsoft.com/identity/claims/identityprovider",
    "value": "Google"
  },
  {
    "type": "sid",
    "value": "A9E0A3B55D35FDAE3A7DCA0126C34E75"
  },
  {
    "type": "jti",
    "value": "43C218D3076EA595B4647CD7B369C405"
  }
]

I have been trying for a few days to fix and I've run out of ideas. I think I'm missing something fundamental here.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source