http://www.huihoo.com/middleware/application_server/sunone/app7_ejb/desecur.html
开发安全的 Enterprise Bean
本节讲述安全管理功能在 EJB 体系架构中的工作方式,并提供针对环境开发安全的 Enterprise Bean 的准则。
注意 |
如果不熟悉 EJB 技术,请参阅 Java 软件教程:
-
http://java.sun.com/j2ee/docs.html
有关 EJB 安全性的信息,请参阅 Enterprise JavaBeans Specification 2.0 第 21 章“安全管理”。
有关应用程序安全性的一般信息,请参阅 Sun ONE 应用服务器开发者指南。 |
本节介绍以下主题:
有关应用程序安全的一般信息,请参阅 Sun ONE 应用服务器开发者指南。
关于安全的 Enterprise Bean
EJB 开发者的主要角色是声明您的应用程序的安全要求,应用程序开发期间,需要满足这些要求。多数情况下,EJB 的业务方法不应包含任何与安全相关的逻辑。
本节介绍以下主题:
授权和身份验证
授权提供对受保护资源的受控访问;授权以身份识别和身份验证为基础。身份识别是通过一个系统实现实体认可的过程。授权是验证计算机系统中用户、设备或其他实体的身份的过程,通常作为允许访问系统中资源的前提条件。
Enterprise Bean 可配置为仅允许具有适当授权级别的用户进行访问。此任务是通过利用 Sun ONE 应用服务器管理界面为应用程序 EAR 和 EJB JAR 文件生成部署描述符来完成的。
安全角色
安全角色是应用程序特有的逻辑用户分组,具体按照通用特征(如客户概要或工作头衔)分类。部署一个应用程序时,可以将角色映射到安全标识,如操作环境中的原则(principal)(作为身份验证结果指定给用户的标识)或组。基于此,具有某种安全角色的用户对 Enterprise Bean 具有关联访问权限。链接为所引用的安全角色的实际名称。
一个组也可以代表一个用户类别,但其范围不同于一个角色的范围。
- 角色是 J2EE 应用程序特有的抽象概念。
- 一个组是一组当前领域中环境特定的用户。组成员身份是通过基本领域实施来确定的。
注意 |
定义方法限制和角色映射时,将领域组和 J2EE 应用程序角色混淆起来是一个常见的错误。这样的混淆会导致不希望的访问结果或不可互操作的应用程序配置。有关领域的信息,请参阅 Sun ONE 应用服务器开发者指南。 |
部署
安全角色引用定义使用 isCallerInRole(字符串名称)从 Enterprise Bean 调用的角色的名称与已为应用程序定义的安全角色的名称之间的映射。此安全性角色引用使一个 Enterprise Bean 可以引用一个现有安全角色。
部署应用程序时,部署者将角色映射到操作环境中存在的全标识。开发 Enterprise Bean 时,您应知道您的用户的角色,但很可能不会准确地知道用户的真实身份。在 J2EE 安全体系架构中,对此设计非常细致。部署您的组件之后,系统管理员将角色映射到默认领域(通常为文件领域)的 J2EE 用户(或组)。
定义安全角色
要为 J2EE 应用程序创建一个角色,需要为 EJB JAR 文件或应用程序中包含的 WAR 文件声明该角色。security-role 元素中定义的安全角色的范围限制在 EJB JAR 文件级别,并适用于 EJB JAR 文件中的所有 Enterprise Bean。
示例
部署描述符中一个安全角色定义的以下示例指定了两个角色名称元素 employee 和 admin。
...
<assembly-descriptor>
<security-role>
<description>
This role includes the employees of the enterprise who
are allowed to access the employee self service
application. This role is allowed to access only
her/his information
</desciption>
<role-name>employee<role-name>
</security-role>
<security-role>
<description>
This role should be assigned to the personnel
authorized to perform administrative functions
for the employee self service application. This
role does not have direct access to
sensitive employee and payroll information
</desciption>
<role-name>admin<role-name>
</security-role>
...
</assembly-descriptor>
声明方法权限
方法权限表示允许哪些角色调用哪些方法。应用程序汇编者使用如下所示方法权限元素在部署描述符中声明方法权限:
- 每个 method-permission 元素都有一个包含一个或多个安全角色的列表以及一个包含一个或多个方法的列表。
-
列出的所有安全角色都可以调用列出的所有方法。列表中的每个安全角色通过 role-name 元素识别,而每个方法(或方法集,如下面所述)则通过方法元素识别。可以使用说明元素将一个可选说明与 method-permission 元素关联。
- 方法权限关系作为个别方法权限元素中定义的所有方法权限的集合进行定义。
- 一个安全角色或一个方法可以出现在多个 method-permission 元素中。
示例
以下部署描述符示例说明如何在部署描述符中给安全角色指定方法权限。部署时将这些方法权限转换为安全元素。
...
<method-permission>
<role-name>employee</role-name>
<method>
<ejb-name>EmployeeService</ejb-name>
<method-name>*</method-name>
</method>
</method-permission>
<method-permission>
<role-name>employee</role-name>
<method>
<ejb-name>AardvarkPayroll</ejb-name>
<method-name>findByPrimaryKey</method-name>
</method>
<method>
<ejb-name>AardvarkPayroll</ejb-name>
<method-name>getEmployeeInfo</method-name>
</method>
<method>
<ejb-name>AardvarkPayroll</ejb-name>
<method-name>updateEmployeeInfo</method-name>
</method
</method-permission>
...
声明安全角色引用
EJB 开发者应负责声明所有安全角色名称的,它们用于角色的部署描述符中的 security-role-ref 元素,这些角色由程序从各自 Enterprise Bean 中进行使用。
- 应用程序汇编者负责将在 security-role-ref 元素中声明的所有安全角色引用链接到 security-role 元素中定义的安全角色。
- 应用程序汇编者使用 role-link 元素将每个安全角色引用链接到一个安全角色。
注意 |
role-link 元素值必须是 security-role 元素中定义的安全角色名称之一。 |
示例
以下部署描述符示例说明如何将名为 payroll 的安全角色引用链接到名为 payroll-department 的安全角色。
<enterprise-beans>
...
<entity>
<ejb-name>AardvarkPayroll</ejb-name>
<ejb-class>com.aardvark.payroll.PayrollBean</ejb-class>
...
<security-role-ref>
<description> This role should be assigned to the payroll
department's employees. Members of this role have access to
anyone's payroll record. The role has been linked to the
payroll-department role.
</description>
<role-name>payroll</role-name>
<role-link>payroll-department</role-link>
</security-role-ref>
....
</entity>
...
</enterprise-beans>
应把此角色指定给薪资部的员工。此角色的成员可以访问任何人的薪资记录。该角色已被链接到 payroll-department 角色。
有关安全角色的进一步信息,请参阅 Sun ONE 应用服务器开发者指南。有关 EJB 访问控制配置的详细信息,请参阅 Enterprise JavaBeans Specification 2.0。
指定安全标识
EJB 汇编者可以随意指定是否将调用者的标识用于执行 EJB 方法,或指定是否使用 run-as 身份。出于此目的,使用部署描述符中的 security-identity 元素。security-identity 元素的值为 use-caller-identity or run-as。
如果没有指定,默认情况下使用调用者标识。.
run-as 标识
run-as 标识建立 Enterprise Bean 进行调用操作时将使用的标识。 run-as 标识不会影响其调用这的标识,这些标识是针对访问 Enterprise Bean 的方法权限而测试的标识。
EJB 汇编者可以使用 run-as 元素为部署描述符中的 Enterprise Bean 定义一个 run-as 标识。run-as 标识总体上适用于 Enterprise Bean,即适用于 EJB 的主接口和组件接口的所有方法 EJB,或适用于消息驱动型 Bean 的 onMessage 方法以及可能调用的 Enterprise Bean 的所有内部方法。
由于汇编者一般不知道操作环境的安全环境,因而按一个逻辑角色名指定 run-as 标识,该逻辑角色名与部署描述符中定义的安全角色之一相对应。然后,部署者必须指定一个作为 run-as 标识的原则使用的安全原则(在操作环境中定义)。安全原则应是一个已经指定给安全角色的与 role-name 元素指定的相同的原则。
使用编程安全
一般来说,应由容器以一种对 EJB 的业务方法透明的方式执行安全管理功能。
注意 |
就像服务件的做法一样,Enterprise Bean 可以使用编程登录。有关详细信息,请参阅 Sun ONE 应用服务器开发者指南 |
EJB 层中的编程安全由 getCallerPrincipal 和 isCallerInRole 方法组成。您可以使用 getCallerPrincipal 方法确定 Enterprise Bean 的调用者,以及使用 isCallerInRole 方法确定调用者的角色。
EJBContext 接口的 getCallerPrincipal 方法返回识别 Enterprise Bean 的调用者的 java.security.Principal 对象。(在此情况下,原则与一个用户相同。在以下示例中,一个 Enterprise Bean 的 getUser 方法返回调用它的 J2EE 用户的名称:
public String getUser()
{
return context.getCallerPrincipal().getName();
}
boolean result = context.isCallerInRole("Customer");
有关如何实施编程安全的详细信息,请参阅 Enterprise JavaBeans Specification 2.0 的第 21 章“安全管理”。
处理不受保护的 EJB 层资源
所有用户都具有匿名角色。默认情况下,匿名角色的值为 ANYONE,该值可在 server.xml 文件中进行配置。因此,如果某个方法权限指定所需角色为 ANYONE(或将匿名角色设置为的任何值),则任何用户都可以访问此方法。
注意 |
如果覆盖某个方法的方法权限不存在,则任何人都可以访问该方法。 |
如果存在方法权限,就始终执行此方法权限。例如,如果设置了某个方法权限,因而 updateEmployeeInfo 方法只能由 employee 角色进行访问,那么,如果没有角色 employee,就始终无法访问此方法。如果没有把 employee 角色映射到任何用户或组,就没有人能够调用 updateEmployeeInfo 方法。