添加角色声明 - 我应该使用 IClaimsTransformer
Adding role claims - should i use the IClaimsTransformer
我们想为当前主体添加很多角色声明(我们使用 Authorize(Roles)
属性),并找到了看起来非常合适的 IClaimsTransformer
。
我们是这样注册的
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);
}
问题:是否有其他或更智能的方法来添加角色声明?
谢谢
拉尔西
另一个选项可以是 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;
}
}
并在 DI 中注册工厂:
services.AddScoped<IUserClaimsPrincipalFactory<User>, AppClaimsPrincipalFactory>();
每当用户提出索赔请求时,它都会change/override索赔。
有关详细信息,请查看 GitHub.
中的源代码
我们想为当前主体添加很多角色声明(我们使用 Authorize(Roles)
属性),并找到了看起来非常合适的 IClaimsTransformer
。
我们是这样注册的
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);
}
问题:是否有其他或更智能的方法来添加角色声明?
谢谢
拉尔西
另一个选项可以是 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;
}
}
并在 DI 中注册工厂:
services.AddScoped<IUserClaimsPrincipalFactory<User>, AppClaimsPrincipalFactory>();
每当用户提出索赔请求时,它都会change/override索赔。
有关详细信息,请查看 GitHub.