Adding Role Claims - Should I Use IClaimsTransformer

We would like to add a lot of complaints to the current leader (we use the attribute Authorize(Roles)) and found that it IClaimsTransformerlooks perfect.

We registered it like this:

 app.UseClaimsTransformation(new ClaimsTransformationOptions
        {
            Transformer = new GetRolesFromDatabaseClaimsTransformer(new RoleManager2(Configuration.GetConnectionString("ourcoolapp")))
        });

And the conversion looks like this:

public Task<ClaimsPrincipal> TransformAsync(ClaimsTransformationContext context)
{
        // A hacky way to not load on all requests. Better ideas?
        if (!context.Context.Request.Path.Value.Contains("api/"))
        {
            return Task.FromResult(context.Principal);
        }

        var roleClaims = RoleManager.GetRolesForUser(context.Principal.Identity.Name).Select(roleName => new Claim("role", roleName));

        var claims = new List<Claim> { };
        var identity = context.Principal.Identity as ClaimsIdentity;
        claims.AddRange(identity.Claims);
        claims.AddRange(roleClaims);

        var userIdentity = new ClaimsIdentity(claims, "local");
        var userPrinicpal = new ClaimsPrincipal(userIdentity);

        return Task.FromResult(userPrinicpal);
}

Q: Are there alternative or more reasonable ways to add role claims?

thank

Larsi

+4
source share
1 answer

Another option might be UserClaimsPrincipalFactory

, , ClaimsTransformer.

UserName UserId . , UserClaimsPrincipalFactory CreateAsync

public class AppClaimsPrincipalFactory : UserClaimsPrincipalFactory<User, Role>
{
    public AppClaimsPrincipalFactory(UserManager<User> userManager,
        RoleManager<Role> roleManager,
        IOptions<IdentityOptions> optionsAccessor, 
        ILogger<AppClaimsPrincipalFactory> logger) 
        : base(userManager, roleManager, optionsAccessor)
    {
        logger.LogInformation("AppClaimsPrincipalFactory ctor");
    }

    public override async Task<ClaimsPrincipal> CreateAsync(User user)
    {
        var principal = await base.CreateAsync(user);
        ((ClaimsIdentity)principal.Identity).AddClaims(new []
        {
            new Claim("Foo", "Bar"), 
        });

        return principal;
    }
}

Factory DI:

services.AddScoped<IUserClaimsPrincipalFactory<User>,  AppClaimsPrincipalFactory>();  

/ , .
GitHub.

+2

Source: https://habr.com/ru/post/1659767/


All Articles