Search code examples
asp.net-coreclaimsopeniddict

Openiddict. Save custom claim to AspNetUserClaims table


I have an auth server based on openiddict 2.0. What I need is to add a custom claim. After some searching, I came to custom implementation of UserClaimsPrincipalFactory:

public class CustomUserClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationUser, IdentityRole>
{
    public CustomUserClaimsPrincipalFactory(
        UserManager<ApplicationUser> userManager,
        RoleManager<IdentityRole> roleManager,
        IOptions<IdentityOptions> optionsAccessor)
        : base(userManager, roleManager, optionsAccessor)
    {
    }

    protected override async Task<ClaimsIdentity> GenerateClaimsAsync(ApplicationUser user)
    {
        var customClaim = new Claim("demo", "some value");

        var identity = await base.GenerateClaimsAsync(user);
        identity.AddClaim(customClaim);            
        return identity;
    }
}

It works and "demo" claim is added to token and is available in User.Claims from the controller action (I am using OAuth2 validation middleware). The only one thing that is confusing is that record with that claim is not added to AspNetUserClaims table. I have found that I can "fix" this by adding it directly to GenerateClaimsAsync method via:

await UserManager.AddClaimAsync(user, customClaim);

and now I am wondering is it correct approach, or there is some simple configuration step, maybe something like "option" flag that I simply need to enable during openiddict setup...


Solution

  • You are adding a claim at two different levels.

    UserManager addresses the store. It looks up and saves data in the database, allowing an async implementation. The ClaimsIdentity on the other hand is not connected to the store.

    Though both have an AddClaim method, the UserManager actually persists the data, while the ClaimsIdentity doesn't.

    The idea of persisted claims is, that once persisted, the claims should be added automatically to the ClaimsIdentity for you. You may have to implement this yourself.