访问控制设计模式

时间:2009-12-17 11:10:05

标签: design-patterns access-control

我正在开发一个PHP应用程序,我想为我的一些对象添加访问控制。我没有将这个问题标记为PHP,因为我觉得这个问题不是特定于语言的。

说我有'服务类'

abstract class Service {


}

许多服务将此作为基类使用。一个伪示例是:

class Companies extends Service {

  function getCompanyInfo($id) {
      //...
  }

}

后来我想添加访问控制。示例'getCompanyInfoById'方法是'读'操作,因此需要'读'特权。

此时我可以通过以下方式实现此目的:

  1. 将accesscontrol添加到Service类。在完成操作并返回结果之前,每个方法(例如getCompanyInfoById)都必须在内部调用'hasPrivilege'方法。
  2. 将所有Service对象包装在某种Proxy对象中,该对象将在调用内部对象中的方法之前检查权限。
  3. 完全分开访问控制,并强制“调用者”在调用方法之前检查权限。
  4. 每个选项的缺点:

    1. 这需要更改所有服务, 并要求他们注意 访问控制。我觉得这样 反对分离关注。
    2. 这打破了OOP功能,例如 多态性。来电者不再 知道什么接口任何服务 支持。
    3. 这是最灵活的,但最大的缺点是现在隐含了检查权限。开发人员可以“忘记”或复杂的代码路径可能导致未经授权的服务被调用。
    4. 是否有更好的方法可以完全解决这个问题?

3 个答案:

答案 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 ...)而变化。这就是为什么要外部维护授权的原因

为此,有一个名为基于属性的访问控制)的模型,该模型是对更为知名的基于角色的访问控制({ {3}})。在RBAC中,访问控制是以身份为中心的。它基于用户,角色和用户所属的组。常常那还不够。在ABAC中,您可以使用用户,资源,上下文(时间)和操作的属性。 ABAC还允许您使用标准化策略语言(或Rego)以普通英语书写策略。云平台(AWS和Google)还实现了自己的语言(分别称为Google IAM和AWS IAM)。

ABAC的一些好处是:

  • 灵活性:您可以更改授权策略而无需触摸您的应用/ API
  • 可重用性:您可以将相同的策略应用于数据,API,应用或基础架构。
  • 可见性:将授权表示为策略,而不是对逻辑进行硬编码,这意味着您可以轻松审核策略并了解可行/不可行
  • 可审计性:使用ABAC,您可以获得有关已授予或拒绝的所有访问的单个日志。

如果您想了解更多信息,请查看ABAC以及ALFA的Wikipedia页面。