ASP Identity 可以处理多租户吗,我在 ASP Identity Web 应用程序中的角色名称有冲突

Can ASP Identity handle multitenancy, I have collisions in role names in ASP Identity web app

在面向网络的 public 应用 多租户应用 中,我正在使用 ASP Identity 2.x.

我让第 3 方的,例如non-profits/comps 自行注册、创建和填充自己的角色和用户。下面的代码没问题,如果它是一个每个人都属于同一家公司的内网场景,它不适用于多个非营利组织

非营利注册者(可以理解)使用相同的名称命名角色,即 ManagersEmployees 等,它们在数据库中 common/same。

我如何扩展 ASP 身份以在多租户方式中分离每个组织的角色,你能帮助我理解设计以及如何扩展它吗,我需要一个子角色吗?即

  1. 我该怎么做才能确保角色在数据库中的每个组织范围内,以便不同的组织可以具有相同的角色名称?
  2. 并且,我在中间层做什么,即用户管理器、角色管理器对象级别(中间层)

    //Roles/Create
    [HttpPost]
    public ActionResult Create(FormCollection form)
    {
        try
        {
            context.Roles.Add(new Microsoft.AspNet.Identity.EntityFramework.IdentityRole()
            {   \ Question - can I add another level here like company??
                Name = form["RoleName"]
            });
            context.SaveChanges();
            ViewBag.ResultMessage = "Role created successfully";
            return RedirectToAction("RoleCreated");
        }
        catch
        {
            return View();
        }
    }`
    
  3. 问题- 添加角色时,添加用户时如何区分角色才能知道哪个角色是哪个公司的?

    public ActionResult RoleAddToUser(string UserName, string RoleName)
    {
        ApplicationUser user = context.Users.Where(u => u.UserName.Equals(UserName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
        var account = new AccountController();
        account.UserManager.AddToRole(user.Id, RoleName);
    
        ViewBag.ResultMessage = "Role created successfully !";
    
        // prepopulat roles for the view dropdown
        var list = context.Roles.OrderBy(r => r.Name).ToList().Select(rr => new SelectListItem { Value = rr.Name.ToString(), Text = rr.Name }).ToList();
        ViewBag.Roles = list;   
    
        return View("ManageUserRoles");
    }
    
  4. 如何获取该非营利组织的角色和用户列表?

    public ActionResult ManageUserRoles()
    {
        var list = context.Roles.OrderBy(r => r.Name).ToList().Select(rr => new SelectListItem { Value = rr.Name.ToString(), Text = rr.Name }).ToList();
        ViewBag.Roles = list;            
        return View();
    }`
    

我猜您确实有某种 TenantIdCompanyId,它是与您合作的租户的标识符。

IdentityRoleIdentityUser是框架对象,建议继承添加自己的属性。你应该这样做:

public class MyApplicationRole : IdentityRole
{
    public int CompanyId { get; set; }
}           


public class MyApplicationuser : IdentityUser
{
    public int CompanyId { get; set; }
}

您还可以在此处添加对公司对象的引用,并将其作为外键 link。这可能会让您更轻松地检索与用户相关的公司对象。

我将根据以上对象尝试回答您的问题:

  1. 创建角色时,您可以将 CompanyId 添加到名称作为前缀。类似于 <CompanyId>#CustomerServiceRole。这将避免名称冲突。同时将CompanyId添加到MyApplicationRoleclass。前缀标识符将避免冲突,对象中的标识符将使公司可以发现角色。或者,您可以实施 RoleValidator 并根据公司内唯一的角色名称进行验证。但是随后您将不得不更改在用户登录时创建用户身份的代码,因为角色 ID 未存储到 cookie 中。

  2. 我认为这是从之前的回答中不言而喻的:

    context.Roles.Add(new Microsoft.AspNet.Identity.EntityFramework.IdentityRole()
    {   
        CompanyId = companyId, // TODO Get the company Id
        Name = companyId.ToString() + "#" + form["RoleName"]
    });
    
  3. 不言自明,请参阅上面的代码片段。

  4. 根据您 link 您在公司中扮演的角色,查询会有所不同。基本上,您需要根据 CompanyId 在公司和匹配角色之间进行连接,然后按非营利标志过滤公司。