我们的应用程序使用多种方式授权访问给定资源。虽然它有效,但它很混乱......好吧,它似乎不对。
我们有明确定义的角色,每个角色都可以访问一组资源,不同的角色可以访问相同的资源。
截至目前,资源只是在数据库表中映射为module
,controller
和action
的MVC操作。
这似乎没问题,但每次我需要添加新的控制器/操作时,我都必须将此资源映射到数据库表。
除了基于角色的授权,用户还可以或多或少地访问另一个角色的资源子集。的例如:
RoleA :资源 a , b , c , d
RoleB :资源 x , y , z
RoleC :资源 1 , 2 , 3
User1 : RoleA 但需要访问资源 y
User2 : RoleB 且 RoleC 但无法访问资源 z
这是作为user_resources
表实现的,其中包含用户有权访问或被拒绝的其他资源的条目(由标志指示)。
我可以通过定制访问创建不同的角色,将角色视为一组权限,但这会导致角色爆炸。
如果这还不够,某些操作只能在模型处于某种状态时执行(每个模型都知道什么时候可以完成)。 例如:只有在用户有权访问编辑资源(通过步骤#1或#2)且对象Order
能够访问时,才能编辑订单被编辑。
Anoter示例:如果用户有权访问Customer
资源并且拥有该客户(他是该客户的联系信息)。
角色,角色组或个人用户可以看到有关模型的更多或更少信息,具体取决于模型的状态。
如何在不放弃授予或限制资源访问权限的情况下简化此授权过程?
我在这里缺少任何模式来统一所有这些授权吗?
答案 0 :(得分:10)
经过很长一段时间,我终于找到了满足我所有要求的答案: http://lostechies.com/derickbailey/2011/05/24/dont-do-role-based-authorization-checks-do-activity-based-checks/
他的解决方案是将所有内容视为一项活动,执行/调用的权限/任何为角色提供的活动,并且用户可以拥有多个角色。
这种方法的亮点在于,对活动本身进行了权限检查,而不是对角色进行权限检查。
答案 1 :(得分:9)
我使用specification pattern实现了访问控制,我发现它直接适用于此。一个核心方法是isSatisfiedBy
。如果z满足,则允许X执行y。例如,如果“具有管理员角色”满足,则允许用户查看“管理页面”。了解isSatisfiedBy
如何非常通用(例如'是id为324的用户','已经登录30分钟','是foo组的成员',...)。然后规则变成以下一般形式:
allow X to do Y if X satisfies Z