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

时间:2018-11-14 23:17:26

标签: asp.net-core asp.net-identity

我正在使用ASP.NET Core Identity设置应用程序,并且尽管已详细阅读了该主题,但我仍在努力寻找适合自己需求的合适的对象。

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

本质上,我有一个要求,即用户可以是一个“区域”(类似于subreddit)的主持人,而只能是另一个“区域”的“用户”。

归结为,当用户登录时,我需要知道他们在每个领域的角色。

就ASP.NET Core身份的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”区域的“用户”和“ private1”区域的初级主持人。

我对此有很多疑问。

首先,通过尝试将两个值填充到“ ClaimType”中,这打破了第一个常规形式。

第二,没有参照完整性。

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

让事情变得复杂的是,我不清楚我是否只需要索偿或索偿和角色的组合。以下问题涉及这个问题,但是根据我的要求,我看不到明确的路径:

Best Practices for Roles vs. Claims in ASP.NET Identity

没有理由我无法通过实现上述解决方案(如“ area:public1”这样的声明)来解决遇到的问题,但这违背了我对系统设计的所有理解。

鉴于上述要求,建议在ASP.NET Core Identity中实施什么?

1 个答案:

答案 0 :(得分:1)

  

这意味着ID为1的用户是该区域的“用户”   “ public1”和“ private1”区域的初级主持人。

如果要实现ID为1的用户具有User角色,而User角色则将public1声明为area类型。

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

    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>();