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 自行注册、创建和填充自己的角色和用户。下面的代码没问题,如果它是一个每个人都属于同一家公司的内网场景,它不适用于多个非营利组织
非营利注册者(可以理解)使用相同的名称命名角色,即 Managers
和 Employees
等,它们在数据库中 common/same。
我如何扩展 ASP 身份以在多租户方式中分离每个组织的角色,你能帮助我理解设计以及如何扩展它吗,我需要一个子角色吗?即
- 我该怎么做才能确保角色在数据库中的每个组织范围内,以便不同的组织可以具有相同的角色名称?
并且,我在中间层做什么,即用户管理器、角色管理器对象级别(中间层)
//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();
}
}`
问题- 添加角色时,添加用户时如何区分角色才能知道哪个角色是哪个公司的?
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");
}
如何获取该非营利组织的角色和用户列表?
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();
}`
我猜您确实有某种 TenantId
或 CompanyId
,它是与您合作的租户的标识符。
IdentityRole
和IdentityUser
是框架对象,建议继承添加自己的属性。你应该这样做:
public class MyApplicationRole : IdentityRole
{
public int CompanyId { get; set; }
}
public class MyApplicationuser : IdentityUser
{
public int CompanyId { get; set; }
}
您还可以在此处添加对公司对象的引用,并将其作为外键 link。这可能会让您更轻松地检索与用户相关的公司对象。
我将根据以上对象尝试回答您的问题:
创建角色时,您可以将 CompanyId
添加到名称作为前缀。类似于 <CompanyId>#CustomerServiceRole
。这将避免名称冲突。同时将CompanyId
添加到MyApplicationRole
class。前缀标识符将避免冲突,对象中的标识符将使公司可以发现角色。或者,您可以实施 RoleValidator
并根据公司内唯一的角色名称进行验证。但是随后您将不得不更改在用户登录时创建用户身份的代码,因为角色 ID 未存储到 cookie 中。
我认为这是从之前的回答中不言而喻的:
context.Roles.Add(new Microsoft.AspNet.Identity.EntityFramework.IdentityRole()
{
CompanyId = companyId, // TODO Get the company Id
Name = companyId.ToString() + "#" + form["RoleName"]
});
不言自明,请参阅上面的代码片段。
根据您 link 您在公司中扮演的角色,查询会有所不同。基本上,您需要根据 CompanyId
在公司和匹配角色之间进行连接,然后按非营利标志过滤公司。
在面向网络的 public 应用 多租户应用 中,我正在使用 ASP Identity 2.x
.
我让第 3 方的,例如non-profits/comps 自行注册、创建和填充自己的角色和用户。下面的代码没问题,如果它是一个每个人都属于同一家公司的内网场景,它不适用于多个非营利组织
非营利注册者(可以理解)使用相同的名称命名角色,即 Managers
和 Employees
等,它们在数据库中 common/same。
我如何扩展 ASP 身份以在多租户方式中分离每个组织的角色,你能帮助我理解设计以及如何扩展它吗,我需要一个子角色吗?即
- 我该怎么做才能确保角色在数据库中的每个组织范围内,以便不同的组织可以具有相同的角色名称?
并且,我在中间层做什么,即用户管理器、角色管理器对象级别(中间层)
//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(); } }`
问题- 添加角色时,添加用户时如何区分角色才能知道哪个角色是哪个公司的?
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"); }
如何获取该非营利组织的角色和用户列表?
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(); }`
我猜您确实有某种 TenantId
或 CompanyId
,它是与您合作的租户的标识符。
IdentityRole
和IdentityUser
是框架对象,建议继承添加自己的属性。你应该这样做:
public class MyApplicationRole : IdentityRole
{
public int CompanyId { get; set; }
}
public class MyApplicationuser : IdentityUser
{
public int CompanyId { get; set; }
}
您还可以在此处添加对公司对象的引用,并将其作为外键 link。这可能会让您更轻松地检索与用户相关的公司对象。
我将根据以上对象尝试回答您的问题:
创建角色时,您可以将
CompanyId
添加到名称作为前缀。类似于<CompanyId>#CustomerServiceRole
。这将避免名称冲突。同时将CompanyId
添加到MyApplicationRole
class。前缀标识符将避免冲突,对象中的标识符将使公司可以发现角色。或者,您可以实施RoleValidator
并根据公司内唯一的角色名称进行验证。但是随后您将不得不更改在用户登录时创建用户身份的代码,因为角色 ID 未存储到 cookie 中。我认为这是从之前的回答中不言而喻的:
context.Roles.Add(new Microsoft.AspNet.Identity.EntityFramework.IdentityRole() { CompanyId = companyId, // TODO Get the company Id Name = companyId.ToString() + "#" + form["RoleName"] });
不言自明,请参阅上面的代码片段。
根据您 link 您在公司中扮演的角色,查询会有所不同。基本上,您需要根据
CompanyId
在公司和匹配角色之间进行连接,然后按非营利标志过滤公司。