永远不会调用JAX-RS Provider的过滤方法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了永远不会调用JAX-RS Provider的过滤方法相关的知识,希望对你有一定的参考价值。
我尝试了遵循this教程并实现了示例中给出的Provider类。
@Provider
@Secured
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {
private static final String REALM = "example";
private static final String AUTHENTICATION_SCHEME = "Bearer";
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
// Get the Authorization header from the request
String authorizationHeader =
requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
// Validate the Authorization header
if (!isTokenBasedAuthentication(authorizationHeader)) {
abortWithUnauthorized(requestContext);
return;
}
// Extract the token from the Authorization header
String token = authorizationHeader
.substring(AUTHENTICATION_SCHEME.length()).trim();
try {
// Validate the token
validateToken(token);
} catch (Exception e) {
abortWithUnauthorized(requestContext);
}
}
private boolean isTokenBasedAuthentication(String authorizationHeader) {
// Check if the Authorization header is valid
// It must not be null and must be prefixed with "Bearer" plus a whitespace
// The authentication scheme comparison must be case-insensitive
return authorizationHeader != null && authorizationHeader.toLowerCase()
.startsWith(AUTHENTICATION_SCHEME.toLowerCase() + " ");
}
private void abortWithUnauthorized(ContainerRequestContext requestContext) {
// Abort the filter chain with a 401 status code response
// The WWW-Authenticate header is sent along with the response
requestContext.abortWith(
Response.status(Response.Status.UNAUTHORIZED)
.header(HttpHeaders.WWW_AUTHENTICATE,
AUTHENTICATION_SCHEME + " realm="" + REALM + """)
.build());
}
private void validateToken(String token) throws Exception {
// Check if the token was issued by the server and if it's not expired
// Throw an Exception if the token is invalid
//TODO validate against database
if(!token.equals("exampleString")) {
throw new AuthenticationException("Invalid token.");
}
}
}
服务器也可以识别此Provider类,可以在日志中看到:
Dez 25, 2017 6:47:09 PM com.sun.jersey.api.core.ScanningResourceConfig logClasses
INFORMATION: Root resource classes found:
class com.jwt.service.AuthenticationEndpoint
class com.jwt.service.HelloWorldService
Dez 25, 2017 6:47:09 PM com.sun.jersey.api.core.ScanningResourceConfig logClasses
INFORMATION: Provider classes found:
class com.jwt.service.AuthenticationFilter
我为注释创建了一个接口:
@NameBinding
@Retention(RUNTIME)
@Target({TYPE, METHOD})
public @interface Secured {
}
并且还注释了我的REST端点。
@GET
@Path("/secured")
@Secured
public Response getUserSecured() {
return Response.status(200).entity("Secured getUser is called").build();
}
即使我的Provider类被识别,但在调用带注释的方法时它仍然不会执行任何操作。即使没有发送身份验证,也不会输出未经授权的状态代码,而是返回“安全的getUser被调用”。
有人知道为什么我的Provider类的filter方法从未被调用过吗?
答案
com.sun.jersey.api
包(在提供的日志中可见)是Jersey 1,而您正在关注的教程涉及球衣2.升级到Jersey 2并且它将起作用。
以上是关于永远不会调用JAX-RS Provider的过滤方法的主要内容,如果未能解决你的问题,请参考以下文章
带有安全过滤器和依赖注入的 jax-rs 1.1,如何实现这一点?
你能用 JAX-RS/Jersey 做传统的 Servlet 过滤吗?
JAX-RS(泽西实现)ExceptionMapper 没有捕获ConstraintViolationException