ASP.NET 核心身份 - UserClaims、UserRoles 和 RoleClaims

ASP.NET Core Identity - UserClaims, UserRoles and RoleClaims

我正在使用 ASP.NET Core Identity 设置一个应用程序,尽管通读了有关该主题的内容,但我仍在努力寻找适合我的要求的应用程序。

熟悉 Reddit 的 subreddit 概念的用户可能会很好地理解我的要求,因为这些概念非常相似。

本质上,我有一个要求,用户可以是一个 "area"(类似于 subreddit)的版主,而只是另一个 "area" 中的 "user"。

归结起来就是当用户登录时,我需要知道他们在每个区域的角色。

我正在努力了解这在 ASP.NET Core Identity 的 AspNetUserClaims 和 AspNetRoles / AspNetUserRoles 方面的实际含义。

我正在考虑像这样定义 AspNetRoles:

Id     Name
1000   User
2000   Junior Moderator
3000   Senior Moderator

然后像这样设置 AspNetUserClaims:

Id     UserId     ClaimType      ClaimValue
1      1          area:public1   1000
2      1          area:private1  2000

这意味着 ID 为 1 的用户是区域 "public1" 的 "user" 和区域 "private1" 的初级版主。

我对此有很多问题。

首先,这打破了第一范式,试图将两个值填充到 "ClaimType"。

其次,没有适当的参照完整性。

仔细观察 AspNetUserRoles,我发现用户和角色之间存在多对多关系。除非我将每个可能区域的每个可能角色定义为 AspNetRole,否则我看不出这是如何工作的。即便如此,我仍不清楚如何以引用安全的方式将其与 AspNetUserClaims 联系起来。

使事情复杂化的是,我不清楚我是只需要声明还是声明和角色的组合。以下问题涉及该主题,但根据我的要求,我没有看到明确的路径:

我没有理由不能通过实施像上面这样的解决方案来解决我遇到的问题,并声称 "area:public1",但这违背了我对系统设计的理解。

鉴于上述要求,ASP.NET Core Identity 中的推荐实施是什么?

This would mean that the user with ID 1 is a "user" of the area "public1" and a junior moderator of the area "private1".

如果要实现 Id 1 的用户具有 User 角色,并且 User 角色具有声明 public1area 类型。

您可以尝试使用下面的代码来配置数据。

    public class HomeController : Controller
{
    private readonly UserManager<IdentityUser> _userManager;
    private readonly RoleManager<IdentityRole> _roleManager;
    public HomeController(UserManager<IdentityUser> userManager
        , RoleManager<IdentityRole> roleManager)
    {
        _userManager = userManager;
        _roleManager = roleManager;
    }
    public async Task<IActionResult> Prepare()
    {            
        var userRole = await _roleManager.CreateAsync(new IdentityRole("User"));
        var role = await _roleManager.FindByNameAsync("User");
        var roleClaims = await _roleManager.AddClaimAsync(role, new Claim("area", "public1"));
        var user = await _userManager.FindByNameAsync("UserName");

        var roleToUser = await _userManager.AddToRoleAsync(user, "User");
        return Ok("ok");
    }

然后,通过

获取用户的声明
    public async Task<IActionResult> Index()
    {
        var user = await _userManager.FindByNameAsync("UserName");
        var roles = await _userManager.GetRolesAsync(user);

        var roleClaims = new List<Claim>();
        foreach (var roleName in roles)
        {
            var role = await _roleManager.FindByNameAsync(roleName);
            var claims = await _roleManager.GetClaimsAsync(role);
            roleClaims.AddRange(claims);
        }

        return View();
    }

以上代码需要配置 .AddRoles<IdentityRole>()

        services.AddDefaultIdentity<IdentityUser>()
            .AddRoles<IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>();