多个组织中具有不同角色的用户
Users in Multiple Organizations with Different Roles
我对为网站设置安全性还很陌生,并且在为 .NET MVC 环境中需要的 authentication/authorization 类型找到正确的 architecture/design/pattern/best 实践时遇到了麻烦。为了做更多的研究,我什至不知道该怎么称呼它。下面是我需要实现的示例。这个叫什么? (我不认为它是多租户。)
Joe 为杂货店连锁店中的几家商店清点库存。 Joe 是商店 A 的库存经理(可以编辑商品),但只是商店 B 的库存文员(只能查看商品)并且无权访问商店 C。
因此,如果 Joe 正在尝试编辑商店 A,他应该能够访问 InventoryController
中的 ActionResult Edit
,但如果正在尝试编辑商店 B 或 C。
直接基于身份或声明的授权对于这种情况是不够的(我不认为),但我不知道 "name" 我需要做的设计进一步的研究。这个设计叫什么?
您可以将其设置为多租户系统。如果每个商店都是拥有自己用户目录的租户,那么 Joe 将需要先登录到商店 A 的不同目录,然后再登录到商店 B,并获得分配的另一个角色。
Joe 将无法登录存储 C,因为他在该目录中没有帐户。
如果您希望用户通过联合系统进行身份验证,则需要为每个商店设置一个角色,并根据用户来自哪个 IdP 来分配这些角色。
这叫做对象级授权(也称为对象级安全性,也称为细粒度授权等)。基本上,权限基于 "ownership" 个对象,或者在这种情况下可能更好, 由 个对象拥有。您需要在商店和员工之间建立多对多关系,负载为 role/grant。例如:
public class StoreEmployee
{
[Key, Column(Order = 1)]
[ForeignKey("Store")]
public int StoreId { get; set; }
public virtual Store Store { get; set; }
[Key, Column(Order = 2)]
[ForeignKey("Employee")]
public int EmployeeId { get; set; }
public virtual Employee Employee { get; set; }
public string Role { get; set; }
}
public class Store
{
...
public virtual ICollection<StoreEmployee> Employees { get; set; }
}
public class Employee
{
...
public virtual ICollection<StoreEmployee> Stores { get; set; }
}
这样,您就可以在操作中使用此关系来验证用户是否具有访问权限:
if (!joe.Stores.Any(m => m.Store == storeA && m.Role == "Manager"))
{
return new HttpUnauthorizedResult();
}
在这里,我通过将 Role
设为字符串来使事情变得简单。您可以使用枚举,甚至可以使用也会保留在数据库中的实际 class。或者,您可以为一般用户绑定现有角色。由你决定。您可能还希望将其转换为 custom action filter.
我对为网站设置安全性还很陌生,并且在为 .NET MVC 环境中需要的 authentication/authorization 类型找到正确的 architecture/design/pattern/best 实践时遇到了麻烦。为了做更多的研究,我什至不知道该怎么称呼它。下面是我需要实现的示例。这个叫什么? (我不认为它是多租户。)
Joe 为杂货店连锁店中的几家商店清点库存。 Joe 是商店 A 的库存经理(可以编辑商品),但只是商店 B 的库存文员(只能查看商品)并且无权访问商店 C。
因此,如果 Joe 正在尝试编辑商店 A,他应该能够访问 InventoryController
中的 ActionResult Edit
,但如果正在尝试编辑商店 B 或 C。
直接基于身份或声明的授权对于这种情况是不够的(我不认为),但我不知道 "name" 我需要做的设计进一步的研究。这个设计叫什么?
您可以将其设置为多租户系统。如果每个商店都是拥有自己用户目录的租户,那么 Joe 将需要先登录到商店 A 的不同目录,然后再登录到商店 B,并获得分配的另一个角色。
Joe 将无法登录存储 C,因为他在该目录中没有帐户。
如果您希望用户通过联合系统进行身份验证,则需要为每个商店设置一个角色,并根据用户来自哪个 IdP 来分配这些角色。
这叫做对象级授权(也称为对象级安全性,也称为细粒度授权等)。基本上,权限基于 "ownership" 个对象,或者在这种情况下可能更好, 由 个对象拥有。您需要在商店和员工之间建立多对多关系,负载为 role/grant。例如:
public class StoreEmployee
{
[Key, Column(Order = 1)]
[ForeignKey("Store")]
public int StoreId { get; set; }
public virtual Store Store { get; set; }
[Key, Column(Order = 2)]
[ForeignKey("Employee")]
public int EmployeeId { get; set; }
public virtual Employee Employee { get; set; }
public string Role { get; set; }
}
public class Store
{
...
public virtual ICollection<StoreEmployee> Employees { get; set; }
}
public class Employee
{
...
public virtual ICollection<StoreEmployee> Stores { get; set; }
}
这样,您就可以在操作中使用此关系来验证用户是否具有访问权限:
if (!joe.Stores.Any(m => m.Store == storeA && m.Role == "Manager"))
{
return new HttpUnauthorizedResult();
}
在这里,我通过将 Role
设为字符串来使事情变得简单。您可以使用枚举,甚至可以使用也会保留在数据库中的实际 class。或者,您可以为一般用户绑定现有角色。由你决定。您可能还希望将其转换为 custom action filter.