永远不会调用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的过滤方法的主要内容,如果未能解决你的问题,请参考以下文章

按特定值过滤时,SQL Server 查询永远不会完成

带有安全过滤器和依赖注入的 jax-rs 1.1,如何实现这一点?

你能用 JAX-RS/Jersey 做传统的 Servlet 过滤吗?

dubbo调用问题之序列化

JAX-RS(泽西实现)ExceptionMapper 没有捕获ConstraintViolationException

Objective-C 完成调用永远不会完成