安全性注释
注释是按照 JSR-175 建议创建的一项功能强大的编程机制。 注释是用于在允许自动生成源代码和配置文件的同时包括受支持安全行为的标准方法。
| 方案分析 | 规则 |
|---|---|
| 仅部署描述符中的安全元数据 | 不需要任何合并,会传播来自部署描述符的安全元数据。 |
| 仅注释中的安全元数据 | 不需要任何合并,会传播使用注释定义的安全元数据。 |
| 部署描述符和注释中的安全元数据 | 会合并来自部署描述符和注释的元数据。 注释中的元数据由部署描述符中同一类型的数据覆盖。 |
- @DeclareRoles(Servlet 2.5 和更高版本以及 EJB 3)
MergeAction 实现会查找使用 DeclareRoles 注释进行注释的所有类。 在指定的每个角色名称的每个已注释类中,如果部署描述符中列示的安全角色未包含具有已注释角色名称的 SecurityRole,那么会创建新的 SecurityRole 并将其添加至安全角色的此列表。
- @RunAs(Servlet 2.5 和更高版本以及 EJB 3)
MergeAction 实现会查找具有 RunAs 注释的所有类。 对于每个带注释的类,它将查找与给定类相关联的 Servlet 或 Enterprise Java Bean (EJB)。 然后,它会确定是否在该 Servlet 或 EJB 的部署描述符中定义了 run-as 元素。 如果找不到 run-as 元素,那么会创建新的 run-as 元素并将其添加至部署描述符。 如果找到 run-as 元素,那么将使用此 run-as 元素而不是创建新的 run-as 元素。 在 RunAs 注释中使用的角色名称必须定义于部署描述符中。
- @DenyAll(仅对于 EJB 3)
MergeAction 实现会查找使用 DenyAll 注释进行注释的所有方法。 对于每个已注释方法,如果该方法未包括在已排除方法的部署描述符列表中,并且部署描述符中不存在 MethodPermission,那么会创建新的 MethodElement 并将其添加至部署描述符中已排除方法的此列表。
- @PermitAll(仅对于 EJB 3)
MergeAction 实现会查找具有 PermitAll 注释的所有类和方法。 对于每个带注释的类,它查找与给定类相关联的 Enterprise Java Bean (EJB)。 然后,它会在此 EJB 的部署描述符内定义的所有 MethodPermission 列表中搜索 MethodElement 的子集。 如果 MethodElement 具有通配符方法名称 ("*") 找不到通配符方法,并且在排除的方法列表或具有安全角色的 MethodElements 列表中不存在通配符方法,将创建新的 MethodPermission 和新的 MethodElement 。 会将新的 MethodPermission 标记为未选中并将其添加至部署描述符中的 MethodPermission 列表。 会将新的 MethodElement 添加至新创建的未选中 MethodPermission 的 MethodElement 列表。 会对所有已注释方法执行类似操作。 不是通配符 MethodElement 而是方法特征符必须与所注释方法的特征符精确匹配。
- @RolesAllowed(仅对于 EJB 3)
MergeAction 实现会查找具有 RolesAllowed 注释的所有类和方法。 对于每个已注释类,它会查找与给定类相关联的 EJB。 然后,它会在此 EJB 的部署描述符内定义的所有 MethodPermission 的列表中查找 MethodElement 的子集。 如果 MethodElement 具有通配符方法名称 ("*") 未找到,并且在排除的方法列表或未选中的 MethodElements列表中不存在通配符方法,将创建新的 MethodPermission 和 MethodElement 。 如果此 EJB 的 MethodPermission 存在并且与注释中找到的那些 MethodPermission 具有完全相同的角色,那么将使用此 MethodPermission 而不是创建新的 MethodPermission。 对于注释中指定的每个角色名称,会创建新的 SecurityRole 并将其添加至 MethodPermission 中的 SecurityRole 列表。如果已新创建 MethodPermission,那么会将它添加至部署描述符中的 MethodPermission 列表。 会将创建的新 MethodElement 添加至 MethodPermission 的 MethodElement 列表。 会对所有已注释方法执行类似处理。 不是通配符 MethodElement 而是方法特征符必须与所注释方法的特征符精确匹配。 此外,对于注释中指定的每个角色名称,如果安全角色的部署描述符列表未包含具有已注释角色名称的 SecurityRole,那么还会创建新的 SecurityRole 并将其添加至安全角色的此列表。
- @ServletSecurity(仅适用于 Servlet 3.0)注: 在此发行版的 WebSphere® Application Server中新增了对 Servlet 3.0 的 ServletSecurity 注释的支持。
当应用程序进行部署时,ServletSecurity MergeAction 实现将查找所有具有 ServletSecurity 注释的 Servlet。 对于每个已注释的 Servlet,它会根据 WebServlet 注释来查找与所给定类相关联的 Servlet。 如果在部署描述符中找不到 ServletSecurity 注释中的 RolesAllowed,那么它将在此部署描述符中为角色创建 role-name 属性。
当应用程序启动时,WebContainer 将检查所有具有 RunAs、declareRoles 和 ServletSecurity 注释的 Servlet,并对 ServletRegistration 注释的 setServletSecurity() 方法设置这些注释。 WebContainer 将通知安全性组件检查所有具有 URL 模式和安全性约束的 ServletRegistration 注释。 然后,安全性组件将确定部署描述符中是否定义了 URL 模式。 如果在部署描述符中未定义 URL 模式,那么会创建然后使用 URL 模式中的安全性约束和 RunAs 角色。 如果在部署描述符中已定义精确匹配,那么会使用部署描述符的 URL 模式中的安全性约束和 RunAs 角色,而不使用注释数据。
注: 当 Web 认证系统属性 com.ibm.wsspi.security.web.webAuthReq设置为 持久时,如果提供了有效的用户名和密码,那么您可以登录到不受保护的 URL。所继承的 Servlet 注释是元数据注释。 请勿在类中指定继承的注释。 如果一个子类没有安全性注释,那么它会从父类自动继承安全性注释。 子类可以通过指定其安全性注释来覆盖父代安全性注释。
以下示例适用于所有不具备约束的 HTTP 方法:@WebServlet ("/Example") @ServletSecurity public class Example extends HttpServlet { …… }以下示例适用于所有不具备 <auth-constraint> 元素并且需要机密 TransportGuarantee 的 HTTP 方法:@WebServlet ("/Example") @ServletSecurity(@HttpConstraint(transportGuarantee = TransportGuarantee.CONFIDENTIAL)) public class Example extends HttpServlet { …… }以下示例适用于所有拒绝了所有访问的 HTTP 方法:@WebServlet ("/Example") @ServletSecurity(@HttpConstraint(EmptyRoleSemantic.DENY)) public class Example extends HttpServlet { …… }以下示例适用于所有不具备约束的 HTTP 方法(GET 和 POST 值除外)。 对于 GET,<auth-constraint> 元素需要在“所有角色”中具有成员资格。 对于 POST,将拒绝所有访问。@WebServlet (name="Example", urlPatterns={"/Example"}) @ServletSecurity((httpMethodConstraints = { @HttpMethodConstraint(value = "GET", rolesAllowed = "ALL ROLE"), @HttpMethodConstraint(value="POST", emptyRoleSemantic = EmptyRoleSemantic.DENY)) }) public class Example extends HttpServlet { …… }以下示例适用于除 GET 之外的所有 HTTP 方法,<auth-constraint> 元素需要在“所有角色”中具有成员资格,并且 GET 方法不具备约束。@WebServlet (name="Example", urlPatterns={"/Example"}) @ServletSecurity(value = @HttpConstraint(rolesAllowed = "ALL ROLE"), httpMethodConstraints = @HttpMethodConstraint("GET")) public class Example extends HttpServlet { …… }以下示例适用于除 TRACE 之外的所有 HTTP 方法,<auth-constraint> 元素需要在“所有角色”中具有成员资格,对于 TRACE,将拒绝所有访问。@WebServlet (name="Example", urlPatterns={"/Example"}) @ServletSecurity(value = @HttpConstraint(rolesAllowed = "ALL ROLE"), httpMethodConstraints = @HttpMethodConstraint(value="TRACE", emptyRoleSemantic = EmptyRoleSemantic.DENY)) public class Example extends HttpServlet { …… }