我想我会用不同的方式来解决这个问题:而不是试图
ClaimsPrincipal
与数据库交谈以确定它们是否属于特定角色,我将修改
索赔原则
并在
实例。
索赔原则
已创建的实例。这可以通过
IClaimsTransformation
代码可能类似于:
public class Startup
{
public void ConfigureServices(ServiceCollection services)
{
// Here you'd have your registrations
services.AddTransient<IClaimsTransformation, ClaimsTransformer>();
}
}
public class ClaimsTransformer : IClaimsTransformation
{
private readonly ApplicationDbContext _context;
public ClaimsTransformer(ApplicationDbContext context)
{
_context = context;
}
public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
var existingClaimsIdentity = (ClaimsIdentity)principal.Identity;
var currentUserName = existingClaimsIdentity.Name;
// Initialize a new list of claims for the new identity
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, currentUserName),
// Potentially add more from the existing claims here
};
// Find the user in the DB
// Add as many role claims as they have roles in the DB
IdentityUser user = await _context.Users.FirstOrDefaultAsync(u => u.UserName.Equals(currentUserName, StringComparison.CurrentCultureIgnoreCase));
if (user != null)
{
var rolesNames = from ur in _context.UserRoles.Where(p => p.UserId == user.Id)
from r in _context.Roles
where ur.RoleId == r.Id
select r.Name;
claims.AddRange(rolesNames.Select(x => new Claim(ClaimTypes.Role, x)));
}
// Build and return the new principal
var newClaimsIdentity = new ClaimsIdentity(claims, existingClaimsIdentity.AuthenticationType);
return new ClaimsPrincipal(newClaimsIdentity);
}
}
为了得到充分的披露
TransformAsync
方法将在每次进行身份验证过程时运行,因此最有可能在每个请求上运行,这也意味着它将在每个请求上查询数据库以获取登录用户的角色。
与修改
索赔原则
是现在
哑的
索赔原则