代码之家  ›  专栏  ›  技术社区  ›  user2806570

ASP.Net Core 2.1注册自定义ClaimsPrincipal

  •  3
  • user2806570  · 技术社区  · 7 年前

    我正在创建一个Windows身份验证应用程序,但角色位于自定义数据库中,而不是广告中,因此我创建了一个自定义ClaimsPrincipal来覆盖通常在广告中查找角色的User.IsInRole()函数。

    我得到错误“主域和受信任域之间的信任关系失败”。

    在ASP.NETMVC5中,我使用了一个定制的RoleProvider,这正是我试图在这里复制的东西。

    自定义索赔sprincipal.cs

    public class CustomClaimsPrincipal : ClaimsPrincipal
    {
        private readonly ApplicationDbContext _context;
    
        public CustomClaimsPrincipal(ApplicationDbContext context)
        {
            _context = context;
        }
    
        public override bool IsInRole(string role)
        {
            var currentUser = ClaimsPrincipal.Current.Identity.Name;
    
            IdentityUser user = _context.Users.FirstOrDefault(u => u.UserName.Equals(currentUser, StringComparison.CurrentCultureIgnoreCase));
    
            var roles = from ur in _context.UserRoles.Where(p => p.UserId == user.Id)
                        from r in _context.Roles
                        where ur.RoleId == r.Id
                        select r.Name;
            if (user != null)
                return roles.Any(r => r.Equals(role, StringComparison.CurrentCultureIgnoreCase));
            else
                return false;
        }
    }
    

    启动.cs

            services.AddIdentity<ApplicationUser, IdentityRole>().AddEntityFrameworkStores<ApplicationDbContext>();
    
            services.AddScoped<ClaimsPrincipal,CustomClaimsPrincipal>();
    

    不确定Startup.cs中的上述代码是否是重写ClaimsPrincipal的正确方法,因为我是.Net核心框架的新手。

    1 回复  |  直到 6 年前
        1
  •  18
  •   ulsc Mickaël Derriey    6 年前

    我想我会用不同的方式来解决这个问题:而不是试图 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 方法将在每次进行身份验证过程时运行,因此最有可能在每个请求上运行,这也意味着它将在每个请求上查询数据库以获取登录用户的角色。

    与修改 索赔原则 是现在 哑的 索赔原则

    推荐文章