4

我們想向當前委託人添加很多角色聲明(我們使用Authorize(Roles)屬性),並發現看起來非常合適的IClaimsTransformer添加角色聲明 - 我應該使用IClaimsTransformer

我們registerd像這樣

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

而且變換是這樣的:

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); 
} 

問題:是否存在替代或添加角色的權利要求的更聰明的方法?

感謝

Larsi

回答

1

另一種選擇可能是UserClaimsPrincipalFactory

它提供方法來創建聲明主體爲給定的用戶,你可以自定義它,就像ClaimsTransformer

默認情況下,它將UserNameUserId添加到要求收集。 爲了從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; 
    } 
} 

和註冊廠DI:

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

它將改變/覆蓋每當用戶的索賠請求的索賠。
欲瞭解更多信息,請訪問GitHub

+0

@Larsi - 其他選項是自定義UserStore並實現GetClaimsAsync,但在這種情況下,聲明存儲在cookie中,如果您有興趣,我們將在其中擁有優點和硬幣,我將在下一個答案中編寫實際示例;) – Soren

+1

考慮ClaimTransformer和UserClaimsPrincipalFactory之間的區別在於您在ClaimsTransformer中(在每個請求中)即時更改聲明,但在其他情況下,您首次對聲明的身份(SignInManager)請求進行自定義,然後將聲明保存在Cookie中; ) – Soren

相關問題