7

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

假设我有一个“服务类”

abstract class Service {


}

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

class Companies extends Service {

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

}

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

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

  1. 将访问控制添加到服务类。每个方法(例如 getCompanyInfoById)都必须在内部调用“hasPrivilege”方法,然后才能完成操作并返回结果。
  2. 将所有服务对象包装在某种代理对象中,该对象将在调用内部对象中的方法之前检查权限。
  3. 完全分离访问控制,并强制“调用者”在调用方法之前检查权限。

每个选项的缺点:

  1. 这需要更改所有服务,并要求它们了解访问控制。我觉得这违背了关注点的分离。
  2. 这破坏了 OOP 特性,例如多态性。调用者不再知道任何服务支持哪些接口。
  3. 这是最灵活的,但最大的缺点是检查权限现在是隐式的。开发人员可能会“忘记”或复杂的代码路径会导致调用未经授权的服务。

有没有更好的方法来解决这个问题?

4

3 回答 3

3

Java EE 模型几乎是第 2 行。您的代码在“容器”中运行,您告诉容器您的接口入口点(servlet 的 URL,EJB 的方法)并定义可以使用这些入口点的角色. 管理员将身份验证信息(例如 LDAP 用户和组)映射到特定角色,并且容器在授予对入口点的访问权限时参考该映射。

这里的关键是容器“知道”你的代码,它实际上是一个非常聪明的代理。

在没有容器的情况下,我将研究代理方法,也许使用某种面向方面的技术。

我认为您是对的,选项 3 非常脆弱,对客户端程序员的责任太大。

于 2009-12-17T11:24:58.373 回答
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 美分

于 2009-12-17T15:19:58.837 回答
3

十年后……世界已经发生了相当大的变化,特别是出现了一种全新的范式:外部授权。公平地说,每个开发框架都有自己的版本(例如,Ruby 中的 CanCanCan 或 Java 中的 Spring Security 或 C# 中的基于声明的授权)。外化授权旨在将授权逻辑与业务逻辑解耦。这个想法是授权需求可能会独立于业务逻辑而发展。例如,您的业务逻辑提供对银行账户的访问(查看/编辑/删除/转移)。功能稳定 - 在不久的将来不会改变。但是,授权需求可能会因立法(GDPR、开放银行……)或不同要求(授权、父子、VIP……)而发生变化,这就是您要保持授权的原因对外

为此,有一个称为基于属性的访问控制( ) 的模型,它是更知名的基于角色的访问控制 ( ) 的演变/扩展。在 RBAC 中,访问控制是以身份为中心的。它基于用户、角色和用户所属的组。很多时候这还不够。在 ABAC 中,您可以使用用户、资源、上下文(时间)和操作的属性。ABAC 还允许您使用标准化的策略语言(或 Rego)以简单的古英语编写策略。云平台(AWS 和 Google)也实现了自己的语言(分别称为 Google IAM 和 AWS IAM)。

ABAC 的一些好处是:

  • flexibility: you can change your authorization policies without touching your apps / APIs
  • reusability: you can apply the same policies to data, APIs, apps, or infrastructure.
  • visibility: express authorization as policies rather than hard-code the logic which means you can easily audit the policies and understand what is possible / what isn't
  • auditability: with ABAC you get a single log of all access that was granted or denied.

If you want to learn more, check out the Wikipedia pages for ABAC and ALFA as well as NIST's page on ABAC.

于 2019-06-07T15:50:21.617 回答