我正在开发一个PHP应用程序,我想为我的一些对象添加访问控制。我没有将这个问题标记为PHP,因为我觉得这个问题不是特定于语言的。
说我有'服务类'
abstract class Service {
}
许多服务将此作为基类使用。一个伪示例是:
class Companies extends Service {
function getCompanyInfo($id) {
//...
}
}
后来我想添加访问控制。示例'getCompanyInfoById'方法是'读'操作,因此需要'读'特权。
此时我可以通过以下方式实现此目的:
每个选项的缺点:
是否有更好的方法可以完全解决这个问题?
答案 0 :(得分:3)
Java EE模型几乎就是2.你的代码在“容器”中运行,你告诉容器你的接口入口点(servlet的URL,EJB的方法)并定义可以使用的角色这些切入点。管理员将身份验证信息(例如LDAP用户和组)映射到特定角色,容器会在授予对入口点的访问权时参考该映射。
这里的关键是Container“知道”你的代码,它实际上是一个非常聪明的代理。
在没有容器的情况下,我会考虑使用代理方法,也许使用某种面向方面的技术。
我认为你是对的,选项3非常脆弱,对客户端程序员来说责任太大了。
答案 1 :(得分:3)
另一种解决方案可能是你的1的一个小变种。
离。
class Service
{
var $ACL = //some hash map with acl
}
class Companies extends Service
{
function getCompanyById($id)
{
//real code
}
}
class SafeCompanies extends Companies
{
//If a method must be "protected" with an ACL, you must override them in this way
function getCompanyById($id)
{
$this->check('read'); //raise an exception if current user haven't READ privilege
parent::getCompanyById($id);
}
}
这样你就不会混淆责任,仍然可以使用多态
我的2美分答案 2 :(得分:0)
十年后……此后世界已经发生了很大的变化,特别是出现了一个全新的范例:外部授权。公平地说,每个开发框架都有其自己的版本(例如Ruby中的CanCanCan或Java中的Spring Security或C#中基于索赔的授权)。外部化授权旨在使授权逻辑与业务逻辑脱钩。这个想法是授权需求可能会独立于业务逻辑而发展。例如,您的业务逻辑提供对银行帐户的访问(查看/编辑/删除/转移)。功能稳定-在不久的将来不会改变。但是,授权需求可能会因立法(GDPR,开放银行...)或不同的要求(委托,父母子女,VIP ...)而变化。这就是为什么要外部维护授权的原因
为此,有一个名为基于属性的访问控制(abac)的模型,该模型是对更为知名的基于角色的访问控制({ {3}})。在RBAC中,访问控制是以身份为中心的。它基于用户,角色和用户所属的组。常常那还不够。在ABAC中,您可以使用用户,资源,上下文(时间)和操作的属性。 ABAC还允许您使用标准化策略语言(rbac或xacml或Rego)以普通英语书写策略。云平台(AWS和Google)还实现了自己的语言(分别称为Google IAM和AWS IAM)。
ABAC的一些好处是: