访问控制的标准做法(设计模式)


9

我正在查看我的界面设计,并且在确定要访问的a user和a的情况下subject,我正在努力确定哪种方法是实现基于角色的访问控制的最“正确”方法user


据我所知,我有三个核心选择(第四个是前三个的混蛋,第五个是第四个的调整):

  1. 使用subject具有以下权限的列表来查询usersubject.allowAccess(user.getPermissionSet)
  2. user使用subject所需的权限列表查询-user.hasPermissionTo(subject.getRequiredPermissions())
  3. 查询第三方以找到权限的交集- accessController.doPermissionSetsIntersect(subject.permissionSet, user.getPermissionSet())
  4. 查询subject/ user,同时将“决定”委托给第三方类
  5. user尝试访问subject,并抛出一个错误,如果不允许访问

我倾向于选项四-具有subject包含一个accessController字段,在其中调用subject.userMayAccess(User user)将操作委托给la:

class Subject {
    public function display(user) {
        if(!accessController.doPermissionSetsIntersect(this.permissionSet, user.getPermissionSet())) {
            display403(); //Or other.. eg, throw an error..
        }
    }
}

..但这又引发了进一步的问题:

  • 应该accessController是字段还是静态类..?
  • 是否应该subject 知道查看权限需要什么权限?
  • 关于召唤,最少知识的原理在哪里起作用subject.display()subject.display()曾经的呼叫者应该知道访问控制有效吗?(subject.display()最终的“模板方法” 在哪里)
  • 具有subject.display()管理访问控制,在用户没有所需权限的情况下引发异常?

在这种情况下,什么被认为是“最佳实践”?实际执行检查的责任应该在哪里发生?

由于这既是一项学术性的专业知识,其又将逐步发展为实施,因此将不胜感激对设计模式的引用。

Answers:


7

最佳做法是使用一种称为“拦截器”模式的方法来拦截对保护区的呼叫。

这可以通过使用AOP或应用于访问入口点的横切关注点来实现。

对象永远不应该知道谁可以查看它。这会不必要地使主题代码复杂化,并且没有理由要求它,除非您无意间为同一功能提供了直接访问机制。

优选地,除了处理拒绝之外,呼叫者和被呼叫者不应该知道访问。但是,问题将取决于您正在实施的系统以及如何获得呼叫者的安全凭证/原理。例如,在SOAP系统中,此信息将添加到SOAP消息的标头中,而在Windows系统中,可通过Windows身份验证机制使用该信息。

如果使用AOP或拦截器模式方法,它将抛出任何必要的异常,并且由客户端(调用方)来处理抛出的所有异常。

这样,您就可以使客户端,服务和身份验证代码保持独立,而不会混杂知识或功能。



2

我认为您的选项3是最接近的选项,但是您应该将and 传递给访问控制器,而不是询问userand subject及其权限集。usersubject

class Subject {
    public function display(user) {
        if(!accessController.checkAccess(this, user, AccessControl.Read)) {
            display403(); //Or other.. eg, throw an error..
        }
    }
}

访问控制器应负责获取权限集并检查访问是否足够。这样,您就可以将访问控制器中的存储逻辑和检查逻辑隔离开来,与用户和主题分开。

您的示例中可能缺少的另一个元素是正在执行的操作。某些用户可能有一些数据,但不能读取更新,删除,执行权等。所以,你可能有一个checkAccess无线控制器上法三个参数:usersubjectoperation。您可能还想提供一些其他信息,checkAccess以从返回有关为何未授予访问权限的信息。

例如,稍后将所有这些都委派给访问控制器,使您可以替换权限的表示方式。您可以从基于角色的访问控制开始,然后再转到基于声明的位置。您可以将权限存储在一个简单的结构中,以开始,然后在不同类型的主题上添加层次结构组/角色和允许的操作。不将权限集放入界面有助于启用此功能。

我认为,无论使用AOP还是一些样板代码来插入它,都没有那么重要。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.