Search code examples
asp.net-core-identityclaimsopeniddict

How to automatically retrieve roles from ASP.NET Core identity?


I'm moving my steps to OpenIDDict and I made my application based on Velusia example.

Everything works fine but I have a question: My access token doesn't include roles.

There's a way to automate the retrieving of .NET Core identity user roles and append them to the User property as Claim before accessing the action in my controller?

The purpose of all is being able to use (for example)

User.IsInRole("MyRole");

Thanks to everyone!


Solution

  • Reading this post gets me in the right direction: Is there a way to dynamically load claims in OpenIddict?

        public class MyClaimTransformation : IClaimsTransformation
    {
        private readonly UserManager<UserInfo> _userManager;
        public MyClaimTransformation(UserManager<UserInfo> userManager)
        {
            _userManager = userManager;
        }
    
        public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
        {
            ClaimsIdentity claimsIdentity = new ClaimsIdentity();
            //claimsIdentity.RoleClaimType = OpenIddict.Abstractions.OpenIddictConstants.Claims.Role;
            //claimsIdentity.NameClaimType = OpenIddict.Abstractions.OpenIddictConstants.Claims.Name;
    
            var claimType = ClaimTypes.Role;
    
    
            if (principal.Identity != null && principal.Identity.IsAuthenticated)
            {
                //Do I already have roles in the claim?
                var roleClaimsAvailable = principal.Claims.Any(x => x.Type == claimType);
                if (!roleClaimsAvailable)
                {
                    //Roles not found, adding:
                    var userProfile = await _userManager.GetUserAsync(principal);
                    if (userProfile != null)
                    {
                        var roles = await _userManager.GetRolesAsync(userProfile);
                        foreach (var role in roles)
                        {
                            claimsIdentity.AddClaim(new Claim(claimType, role));
                        }
    
                        principal.AddIdentity(claimsIdentity);
                    }
                }
            }
    
            return principal;
        }
    
    }
    

    Than we need to register in the Startup.cs as a service:

    //Adding roles on access token incoming
    builder.Services.AddTransient<IClaimsTransformation, MyClaimTransformation>();