提取 HTTP 标头
您不需要在 JAX-RS 端点中使用 HttpServletRequest 来从请求中获取 HTTP 标头。相反,你可以注入HttpHeaders:
@Context
HttpHeaders httpHeaders;
然后你可以使用HttpHeaders API 来获取标题值:
如果您需要标准 HTTP 标头的值,请考虑使用 constants available in the HttpHeaders API:
// Get the value of the Authorization header
String authorizationHeader = httpHeaders.getHeaderString(HttpHeaders.AUTHORIZATION);
使用过滤器
由于您正在执行身份验证和/或授权,我建议您使用过滤器,这样您就可以保持 REST 端点精简并专注于业务逻辑。
为了将过滤器绑定到您的 REST 端点,JAX-RS 提供了元注释@NameBinding,可以按如下方式使用:
@NameBinding
@Retention(RUNTIME)
@Target({TYPE, METHOD})
public @interface Secured { }
@Secured 注解将用于装饰一个过滤器类,它实现了ContainerRequestFilter,允许您处理请求。
ContainerRequestContext 帮助您从 HTTP 请求中提取信息(更多详细信息,请查看ContainerRequestContext API):
@Secured
@Provider
@Priority(Priorities.AUTHENTICATION)
public class SecurityFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
// Use the ContainerRequestContext to extract information from the HTTP request
// Information such as the URI, headers and HTTP entity are available
}
}
如果用户未经过身份验证/授权,ContainerRequestFilter#filter() 方法是中止请求的好地方。为此,您可以使用ContainerRequestContext#abortWith() 或抛出异常。
@Provider 注释标记了扩展接口的实现,在提供程序扫描阶段应该可以被 JAX-RS 运行时发现。
要将过滤器绑定到您的端点方法或类,请使用上面创建的@Secured 注释对其进行注释。对于被注释的方法和/或类,将执行过滤器。
@Path("/")
public class MyEndpoint {
@GET
@Path("{id}")
@Produces("application/json")
public Response myUnsecuredMethod(@PathParam("id") Long id) {
// This method is not annotated with @Secured
// The security filter won't be executed before invoking this method
...
}
@DELETE
@Secured
@Path("{id}")
@Produces("application/json")
public Response mySecuredMethod(@PathParam("id") Long id) {
// This method is annotated with @Secured
// The security filter will be executed before invoking this method
...
}
}
在上面的示例中,安全过滤器将仅针对mySecuredMethod(Long) 执行,因为它带有@Secured 注释。
您可以为 REST 端点设置任意数量的过滤器。为确保过滤器的执行顺序,请使用@Priority 对其进行注释。
强烈建议使用Priorities 类中定义的值之一(将使用以下顺序):
如果您的过滤器未使用@Priority 注释,则过滤器将以USER 优先级执行。
其他信息
您可能会发现这个answer 很有用。