使用注释保护 JAX-RS 资源
您可以使用指定安全设置的注解来保护 Java™ API for RESTful Web Services (JAX-RS) 资源。
开始之前
此任务假设您开发了该应用程序并标识了 JAX-RS 资源,您希望使用安全性注解来对其进行保护。
关于此任务
您可以使用 JSR 250 支持的安全性注解来保护 JAX-RS 资源。您可以使用以下注解将权限语义添加到 JAX-RS 应用程序资源:
- @PermitAll - 指定允许所有安全角色来访问 JAX-RS 资源
- @DenyAll - 指定不允许任何安全角色来访问 JAX-RS 资源
- @RolesAllowed - 指定允许访问 JAX-RS 资源的安全角色
您可以选择在类级别还是在方法级别进行注解。以下规则管理安全性注解:
- 方法级别注解优先于类级别的注解。
- 在以下代码片段中,由 /addresses 的 @GET 和 @Path 注解引用的 JAX-RS 资源以及相应的 getList() 方法未受限,且开放来供公共使用。但是,由 /addresses 的 @PUT 和 @Path 注解引用的资源以及相应的 updateList() 方法需要 Manager 的角色;例如:
@Path(value="/addresses") @PermitAll public class AddressBookResource { @GET @Produces(value="text/plain") public String getList() { } @PUT @RolesAllowed(“Manager”) to public void updateList(String[] books) { } }
- 安全的注解是互斥的。
- 这表示每个资源最多只由其中一个安全注释进行管理。例如,以下示例无效,因为同时指定了 @PermitAll 和 @RolesAllowed:
@Path(value="/addresses") @PermitAll @RolesAllowed(“Employee”) public class AddressBookResource { @GET @Produces(value="text/plain") public String getList() { } }
在先前代码示例中,@RolesAllowed 注解优先,而忽略 @PermitAll 注解。 类似地,如果同时指定了 @RolesAllowed 注解和 @DenyAll 注解,那么 @DenyAll 注解优先。
类似地,如果在方法或类级别同时指定了 @PermitAll 和 @DenyAll 注解,那么 @DenyAll 注解优先,因为它通过遵守安全缺省原则来确保安全性。
如果 @PermitAll、@DenyAll 和 @RolesAllowed 注解都存在于方法或类级别,那么 @DenyAll 注解优先于 @RolesAllowed 和 @PermitAll。这些注解的优先顺序如下:- @DenyAll
- @RolesAllowed
- @PermitAll
- 继承规则
- 在类级别添加的 JSR 250 注解只影响其注解的类以及子资源的相应方法。 在类级别指定的注解不影响从超类继承的资源。
- 覆盖方法的规则
- 对应于子类中的覆盖方法的资源注解优先于包含在父类中的注解。在以下片段中,LocalAdministrator 角色用于访问 /addresses/local 子资源;例如:
s@Path(value="/addresses") @PermitAll public class AddressBookResource { @GET @Produces(value="text/plain") public String getList() { } @PUT @RolesAllowed(“Administrator”) public void updateList(String books) { } } @Path(value="/addresses") @PermitAll public class LocalAddressBookResource extends AddressBookResource { @PUT @RolesAllowed(“LocalAdministrator”) @Path(value=”local”) public void updateList(String books){ } }
- @RolesAllowed 注意事项
- 您不能在一个资源上同时拥有多个 @RolesAllowed 注解。例如,您可以实现:
使用以下代码片段:@RolesAllowed("role1") @RolesAllowed("role2") public String foo() { }
@RolesAllowed({"role1", "role2"}) public String foo() { }
- 针对使用安全注解以及安全性约束配置的注意事项
安全注解遵循声明式安全性模型。 在部署描述符 web.xml 文件中配置的安全性约束优先于以编程方式在应用程序中注解的安全性约束。对于 JAX-RS 资源的开发者,重要的是考虑跨可配置安全性约束和注释的安全性约束的平衡。注解的约束是任何配置的安全性约束的附加项。 在 Web 容器运行时环境检查了在 web.xml 文件中配置的安全性约束之后,JAX-RS 运行时环境检查注解的约束。
在 web.xml 文件中配置认证约束。在以下示例 web.xml 文件中,定义了 SecurityConstraint_1 安全性约束。此约束用于要求对应用程序的认证。此外,SecurityConstraint_1 安全性约束定义关于对应于 JAX-RS 资源的 URL 模式的约束。访问对应于其中某个约束的 JAX-RS 资源时,执行授权检查。仅在验证了配置的约束之后,才执行对声明式安全性注解的访问检查。<web-app id="WebApp_someID"> <servlet> <servlet-name>AddressBookAppSample</servlet-name> <servlet-class> org.apache.wink.server.internal.servlet.RestServlet </servlet-class> <init-param> <param-name>javax.ws.rs.Application</param-name> <param-value>jaxrs.sample.AddressBookApplication </param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>AddressBookApp</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> <security-constraint id="SecurityConstraint_1"> <web-resource-collection id="WebResourceCollection_1"> <web-resource-name>AddressBookAppSample</web-resource-name> <description>Protection area for Rest Servlet</description> <url-pattern>/*</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> <http-method>PUT</http-method> </web-resource-collection> <auth-constraint id="AuthConstraint_1"> <description>Role1 for this rest servlet</description> <role-name>Role</role-name> </auth-constraint> <user-data-constraint id="UserDataConstraint_1"> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> <security-role id="SecurityRole_1"> <description>This Role is used to drive authentication </description> <role-name>Role1</role-name> </security-role> <login-config> <auth-method>BASIC</auth-method> <realm-name>test realm</realm-name> </login-config> </login-config> </web-app>
在先前的 web.xml 文件样本中,Role1 用于整个应用程序。如果您仅定义声明式安全性注解且您未使用来自 web.xml 文件的授权约束,那么可以将 JAX-RS 应用程序的该角色映射至 AllAuthenticated 特殊主体集以进行用户认证。
过程
- 确定是否存在由 JAX-RS 应用程序的 web.xml 文件定义的安全性约束。
- 配置 web.xml 文件以添加安全性约束。 在部署描述符 web.xml 文件中配置的安全性约束优先于以编程方式在应用程序中注解的安全性约束。
- 确定除了 web.xml 文件中的任何约束,您是否要添加安全注解。 决定您是否要添加 @PermitAll、@DenyAll 和 @RolesAllowed 注解之一来为 JAX-RS 资源提供附加安全性。 考虑关于添加安全注解的规则,例如先前描述的优先顺序和继承。
结果
您使用声明式安全性注解定义了安全 JAX-RS 资源。
示例
以下代码片段演示您可以如何使用安全注解来保护 JAX-RS 资源。在此示例中,/addresses 根资源与 @PermitAll 注解关联,因此允许所有用户使用对应于 @GET 和 @Produces(value="text/plain") 方法的子资源,因为此资源没有引入自己的安全注解。但是,对应于 @PUT 方法的子资源与其拥有的 @RolesAllowed 注解关联且需要 Administrator 角色。
@Path(value="/addresses")
@PermitAll
public class AddressBookResource {
@GET
@Produces(value="text/plain")
public String getList() {
}
@RolesAllowed(“Administrator”)
@PUT
public void updateList(String books) {
}
}