background image

用于将外部安全管理器与应用服务器集成。JACC 提供了将安全授权的权限检查委托给外

 

部提供程序的功能。由于授权检查是在容器将控制权交给应用程序前进行的,因此 JACC 
具有能够清楚区分自定义授权逻辑和应用程序逻辑的优势,从而满足了关注点分离的需

 

求。不过,使用 JACC 

 

时有一些方面需要特别注意,因此有必要更深入地探讨 JACC,以

 

准确了解其执行的工作以及可对其加以应用的场合。我们稍后将对 JACC 进行更为详细的
讨论。
  基于实例的授权
  顾名思义,基于实例的授权就是将访问权限授予某个对象的特定实例。基于实例的授
权通常使用访问控制列表(Access Control List,ACL)

 

来保护实例,而 ACL 存储在某种

 

类型的策略存储区中,并且可用来制定访问决策。可以将 J2EE 

 

角色作为 ACL 使用,不

过这个方法可能会不方便。正如我们前面所讨论的,J2EE 角色终究只是一个名称,是可

 

以绑定到任何一组主体的逻辑构造。这种方法不能很好地扩展来大量使用 ACL,也不能

 

处理在应用程序执行时动态修改 ACL 的情况;因为我们曾提到,部署描述符在应用程序

 

启动时以静态方式定义 J2EE 角色。考虑到这些限制,在许多情况下,更好的方法可能是

 

使用外部安全解决方案或 ACL 基于实例的安全性自定义框架。

 

  为了更便于理解,让我们看一个例子。假定我们有一个新的 J2EE 人力资源系统,可
允许用户执行打印相关的任务,如将文档发送到打印机和查看与管理打印队列。由于可打
印数据的敏感特征,需要进行某些限制。例如,可能存在有关授权哪些用户使用或管理哪
些打印机的规则。还可能存在有关在每天的特定时段使用打印机的规则;或许会考虑连夜
在特定的打印机上打印敏感材料。

 

  我们可以使用标准的 J2EE 基于角色的安全性来管理打印机访问。例如,可以为打印
机 和 所 需 访 问 类 型 的 每 种 组 合 定 义 一 个 角 色 , 最 终 得 到
“Allowed_to_print_to_PrinterX” “

或 Allowed_to_manage_queue_for_PrinterY”之类

 

的角色。然后,我们必须在应用程序中编写代码,以使用 isUserInRole() 调用遍历所有
可能的角色,从而验证当前用户是否被授权执行他们所尝试的任何打印相关操作,而且
我们必须将每个角色绑定到相应的用户注册中心条目。
  正如您所看到的,这并不是授权需求的一个条理非常清楚的实现。添加任何新打印机
都会要求对应用程序进行更改;而有关何人可以进行何种操作的规则的变化则会要求重新
将这些角色绑定到主体,并重新部署应用程序。此外,我们尚未开始考虑时段问题。我们

 

需要能够存储与每台打印机对应的可配置信息,但在标准 J2EE 授权模式中,实际上却
没有任何地方能够放置此类信息。
  现在,如果我们要使用独立的授权服务,这可以极大地简化解决方案,因为我们将
只需要询问授权服务,当前用户是否可以对某个对象执行某项操作。所有这些都将外部化,
从而极大地简化了编程模型,并使得对外部提供程序的更改以实时的方式反映到正在运
行的应用程序中。我们稍后将再次对此问题进行讨论。
  所有权关系
  直接所有权是用户和某些受保护数据间的一种十分常见的基于实例的关系。例如,在
经纪业应用程序中,理财顾问可以查看其个人客户的帐户,但却不能查看公司的其他客
户的帐户。部门经理可以查看所属的理财顾问的所有客户的所有帐户,但却不能查看其他
部门的客户的帐户,诸如此类。在这种情况下,权限内置到应用程序的数据结构中。
  应用程序很少会采用以下这种方式,即向用户界面提供用于检索所有数据的帐户列

 

表,然后再向每一行应用基于 ACL 

 

的权限。这里存在的主要问题是性能:与在 Java 代