首页 文章

ASP.NET Core 2.1自定义RoleProvider与Windows身份验证

提问于
浏览
4

我正在将应用程序从ASP.Net MVC 5框架迁移到新的.Net Core 2.1 .

我在MVC 5项目中使用了Windows身份验证和自定义RoleProvider,如下面的链接所示 .

ASP.NET MVC How to create a custom role provider

如何在Core 2.1中完成相同的操作,因为它似乎不包含RoleProvider功能?

我遇到的每个示例都使用IdentityUser和IdentityRole的个人帐户 .

用户和角色的自定义表格:

public class User
{
    public User() { UserRoles = new HashSet<UserRole>(); }

    [Key]
    public string Id { get; set; }

    [StringLength(50)]
    [Required]
    public string Logon { get; set; } //The users Active Directory Username

    public bool Active { get; set; }

    public ICollection<UserRole> UserRoles { get; set; }

}


public class Role
{
    public Role() { UserRoles = new HashSet<UserRole>(); }

    [Key]
    public string Id { get; set; }

    public string Name { get; set; }

    public ICollection<UserRole> UserRoles { get; set; }
}

编辑:

我添加了一个CustomClaimsPrincipal,它类似于:

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));
            //(ApplicationUser)_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;
    }
}

并添加到Startup.cs

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

        services.AddScoped<ClaimsPrincipal, CustomClaimsPrincipal>();

但它似乎仍然采用原始的ClaimsPrincipal IsInRole函数而不是覆盖,我认为这就是为什么我收到错误消息“主域和可信域之间的信任关系失败” .

2 回答

  • 0

    管理网络核心中的自定义权限通常通过声明来完成 . 您可以通过aspnet身份(How to add claims in ASP.NET Identity)执行此操作,也可以编写自己的中间件 .

    获得声明后,您需要创建策略 . 这是通过 ConfigureServices 方法中的 Startup.cs 类完成的 .

    services.AddAuthorization(options =>
            {
                options.AddPolicy("HR", policy => policy.RequireClaim("HRTeam"));
                options.AddPolicy("Helpdesk", policy => policy.RequireClaim("HelpdeskTeam"));
            });
    

    然后使用 Authorize 属性修饰您的控制器/操作

    [Authorize(Policy="Helpdesk")]
    public class HelpDeskController : Controller
    
  • 1

    我有同样的问题 - 帖子中给出的解决方案没有帮助,但评论指出了我正确的方向 . 您需要向ClaimsPrincipal添加声明 .

    第1步:创建一个ClaimsTransformer - 替换“Admin”并为您从数据库中提取的每个角色添加单独的声明

    using System.Security.Claims;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Authentication;
    
    public class ClaimsTransformer : IClaimsTransformation
    { 
        public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
        {
            var ci = (ClaimsIdentity) principal.Identity;
            var c = new Claim(ci.RoleClaimType, "Admin");
            ci.AddClaim(c);
            return Task.FromResult(principal);
        }
    }
    

    步骤2:将ClaimsTransformer添加到Startup.cs的ConfigureServices方法

    services.AddAuthentication(Microsoft.AspNetCore.Server.IISIntegration.IISDefaults.AuthenticationScheme);
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    services.AddSpaStaticFiles(configuration =>
    {
        configuration.RootPath = "ClientApp/dist";
    });
    
    services.AddSingleton<IClaimsTransformation, ClaimsTransformer>();
    

    第3步:您现在可以在控制器中添加基于角色的授权属性

    [Authorize(Roles = "Admin")]
    [HttpGet("[action]/{id}")]        
    public User GetUser([FromRoute] int id)
    {
        UserLogic ul = new UserLogic();
        return ul.GetUser(id);
    }
    

相关问题