Search code examples
asp.net-coreopenid-connect

AspnetCore 3.1 OpenIdConnectEvent using claims from ClaimActions.MapJsonKey


I'm trying to add custom claims to the logging in user principal using the OnTokenValidated event. To get these claims I need to fetch data from the database.

The event is called, I can access the database and everything should be fine:

options.Events.OnTokenValidated = requestContext=> {
var ctx = requestContext.HttpContext.RequestServices.GetRequiredService<IPersistenceContext>();
    var principal = requestContext.Principal;

    var userExternalId = principal.FindFirstValue(IdentityModel.JwtClaimTypes.Subject);
    var user = await ctx.Users
        .FirstOrDefaultAsync(u => u.ExternalId == userExternalId);
//do stuff with the user
}

Except, in the OnTokenValidated I would need to access claims that are mapped using ClaimActions.MapJsonKey. For example, I would need to access the user's roles, mapped like this: options.ClaimActions.MapJsonKey(JwtClaimTypes.Role, JwtClaimTypes.Role, JwtClaimTypes.Role);

Now when I try to check the principal's claims in the OnTokenValidated, there are no role claims. Only the 'standard' OIDC claims are present.

The roles are available to the application after the login has completed, so their mapping works as expected.

How can I access the role claims (and anything else mapped via ClaimActions.MapJsonKey) in an OpenIdConnectEvent?


Solution

  • Instead of hocking into the OpenIDConnect events, why not hock into the Cookie handler events instead? In it you have for example the OnSigningIn that could be useful for you.

    The relationship between the two handlers are as the diagram below shows: enter image description here

    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

    Cookie handler will get the final ClaimsPrincpal user object from OpenIdConnect and from that one create the cookie.