ASP.NET 具有 Windows 身份验证的核心 2.1 自定义 RoleProvider

ASP.NET Core 2.1 Custom RoleProvider with Windows Authentication

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

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

我如何在 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 函数而不是覆盖,我相信这就是我收到错误消息的原因 "The trust relationship between the primary domain and the trusted domain failed."

在 net core 中管理自定义权限通常是通过声明来完成的。您可以通过 aspnet identity(How to add claims in ASP.NET Identity) 执行此操作,也可以编写自己的中间件。

有了索赔后,您需要创建保单。这是通过 ConfigureServices 方法中的 Startup.cs class 完成的。

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

然后用 Authorize 属性装饰你的 controllers/actions

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

我遇到了同样的问题 - post 中给出的解决方案没有帮助,但评论为我指明了正确的方向。您需要将声明添加到您的 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);
}