我正在使用这个结构的MVC应用程序:
Request
V
FrontController <-> Router
V
Controller <-> Model
V
View
我还有两个组件需要放在这个结构中:
-
Authentification
:使用$_SESSION
全局变量登录用户; -
RBAC
: 基于角色的访问控制,可以检查角色是否被授予"资源" (Controller
方法)。
每个用户都可以拥有任意数量的角色(也可以没有角色)。
现在,我需要把这两个组件放在我的应用程序中,我需要它们能够:
- 如果
User
没有被授权,而Request
需要一个被授权的User
来执行,客户端应该被重定向到登录页面; - 如果
RBAC
看到authUser
没有角色有权访问授予所需的执行"ressource"Controller
' s方法,Controller
的方法应与知识仍有被执行死刑的可能性,但User
没有权限这样做(示例:User
写文章,但没有正确的发布,所以这篇文章是保存为草稿,User
告知Moderator
必须发布)。
我已经有一些想法在哪里找到Authentification
和RBAC
,但我不确定:
-
Authentification
可以放在FrontController
或Router
中; -
RBAC
可以放在FrontController
或Controller
中。
我看到有人把RBAC
放在模型里,但我不明白为什么。
Authentification
和RBAC
组件放在哪里?谢谢!
根据我的经验,随着新特性的添加,访问控制业务逻辑会发生变化,因此在访问控制系统中设计灵活性和移动性是值得的。因此,我将Authentication和RBAC设计为单独的特征,然后根据需要将这些特征合并到控制器空间中。
如前所述,听起来身份验证特性最好合并到您的前端控制器中:您知道所有依赖的控制器都需要身份验证,因此在生命周期的早期合并该检查以释放请求套接字。如果你的需求发生了变化,需要对某些控制器进行非门控,你可以将该特性下推到特定的控制器或基控制器类中。对于RBAC,它可以全局应用于所有控制器,也可以局部应用于某些控制器。例如,您的FrontController可以查询RBAC来构建路由表,而从属控制器将使用RBAC来满足其特定需求。
但有一件事需要考虑:您可能还需要在模型中使用一些RBAC。也就是说,某些角色可能对某些模型中的某些字段具有有限的访问权限:角色A可以访问模型X的所有字段,但角色B只能读取模型X的字段1、2和3(相信我,我看到过关于角色可以查看哪些字段并对哪些字段进行操作的非常非常复杂的规则。)工程RBAC作为一个控制器特性可能会使移植到模型空间变得困难。因此,您可能会发现将RBAC设计为服务委托并按需注入它会更好。使用一个配置良好的IoC容器,服务委托就像编译时训练一样简单。
最后,我要补充一点,您将需要对这两种方法进行大量测试(毕竟它们很重要)。所以无论你选择什么,都要进行工程设计,以便测试。在我看来,trait和委托都很容易单独测试,而且对于实现必要的逻辑来说,两者都是很好的选择。
在典型的MVC应用程序中,身份验证检查(即"如果不验证,那么停止并呈现登录页面")在处理请求的早期就完成了,而业务逻辑(即。"如果用户有此权限,则会发生此操作,否则会发生此操作")在"C"(控制器)内处理。
大多数框架都有一种机制来进行测试,比如你所描述的身份验证检查——名称各不相同,但我经常看到它被称为"中间件"。
基于角色的访问控制完全是你的实现。