ASP Identity可以处理多租户,我在ASP Identity Web app中的角色名称中发生了冲突

时间:2015-09-16 06:57:10

标签: security authentication asp.net-identity multi-tenant

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

我让第三方例如非营利组织/组合自我注册,创建和填充自己的角色和用户。下面的代码很好,如果它是一个内部网情况,每个人都属于同一家公司,它不会为多个非营利组织工作

非营利性注册人(可以理解的是)使用相同的名称命名角色,即ManagersEmployees等,这些角色在数据库中是相同的/相同的。

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

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

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

1 个答案:

答案 0 :(得分:1)

我猜你确实有某种TenantIdCompanyId,它是您正在使用的租户的标识符。

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

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


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

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

根据上述对象,我会尝试回答您的问题:

  1. 创建角色后,您可以将CompanyId附加到名称作为前缀。像<CompanyId>#CustomerServiceRole这样的东西。这样可以避免姓名冲突。同时将CompanyId添加到MyApplicationRole类。前缀标识符将避免冲突,对象中的标识符将使公司可以发现角色。或者,您可以实施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. 根据您将角色与公司关联的方式,查询将有所不同。基本上,您需要在公司和基于CompanyId的匹配角色之间进行联接,然后通过非盈利标志过滤公司。