4

Wir möchten dem aktuellen Principal viele Rollenansprüche hinzufügen (wir verwenden das Authorize(Roles) Attribut) und fanden die IClaimsTransformer, die wie eine perfekte Passform aussieht.Hinzufügen von Rollenansprüchen - sollte ich den IClaimsTransformer verwenden

Wir registerd haben es wie diese

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

Und die Transformation ist wie folgt:

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

Frage: Sind alternative gibt, oder intelligente Art und Weise der Rolle Ansprüche Zugabe?

Dank

Larsi

Antwort

1

Eine weitere Option könnte UserClaimsPrincipalFactory

Es stellt Verfahren werden Ansprüche Auftraggeber für einen bestimmten Benutzer zu erstellen und Sie können es wie ClaimsTransformer anpassen.

Standardmäßig werden UserName und UserId zur Sammlung von Ansprüchen hinzugefügt. Um es gestalten Sie Treiber von UserClaimsPrincipalFactory können und 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; 
    } 
} 

außer Kraft setzen und die Fabrik in DI registrieren:

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

Es wird die Forderung ändern/außer Kraft setzen, wenn die Forderungen angeforderten des Benutzers.
Weitere Informationen finden Sie unter Quelle unter GitHub.

+0

@Larsi - und andere Option ist die Anpassung von UserStore und implementieren GetClaimsAsync, aber in diesem Fall speichert speichert in Cookie, das hat seine Pros und Münzen, wenn Sie interessiert sind, werde ich praktische Beispiel in der nächsten Antwort schreiben;) – Soren

+1

Betrachten dass der Unterschied zwischen ClaimsTransformer und UserClaimsPrincipalFactory darin besteht, dass Sie in ClaimsTransformer die Ansprüche im laufenden Betrieb (in jeder Anfrage) ändern, in anderen Fällen jedoch zuerst die Identity (SignInManager) -Anfrage für Claims anpassen und danach die Claims im Cookie speichern;) – Soren

Verwandte Themen