0

I am trying to fix my JAX RS API here.

I use Java 8 Security API (with Jersey 2) for authentication with JWT through my JWTAuthenticationMechanism class which is represented below.

public class JWTAuthenticationMechanism implements HttpAuthenticationMechanism {
    @Override
    public AuthenticationStatus validateRequest(HttpServletRequest request, HttpServletResponse response, HttpMessageContext context) {
        if (ok) {
            return context.notifyContainerAboutLogin(..., ...);
        else {
            return context.responseUnauthorized();
        }
    }
}

And I also use CORSFilter to enable CORS on my server.

@Provider
public class CORSFilter implements ContainerResponseFilter {
    @Override
    public void filter(ContainerRequestContext req, ContainerResponseContext res) throws IOException {
        res.getHeaders().add("Access-Control-Allow-Origin", "*");
        res.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
        res.getHeaders().add("Access-Control-Allow-Credentials", "true");
        res.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
    }
}

My problem is that when JWTAuthenticationMechanism do context.responseUnauthorized(), it responds directly to the client without passing through my CORSFilter.

Then, client receives CORS error instead of a HTTP 401 Unauthorized.

Everything looks fine when I add manually CORS headers before using responseUnauthorized, so responseUnauthorized is really bypassing the filter.

context.getResponse().addHeader("Access-Control-Allow-Origin", "*");
context.getResponse().addHeader("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
context.getResponse().addHeader("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
context.getResponse().addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
return context.responseUnauthorized();

Any idea ?

robinvrd
  • 1,760
  • 12
  • 28
  • @user7294900 `@PreMatching` is for `ContainerRequestFilter` not Reponse ones. https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/PreMatching.html – robinvrd Jul 20 '20 at 09:26
  • there's a full example of CorsFilter in https://stackoverflow.com/questions/28065963/how-to-handle-cors-using-jax-rs-with-jersey – Ori Marko Jul 20 '20 at 09:28
  • @user7294900 which is exactly what I have, the long version implementing both `ContainerRequestFilter` and `ContainerResponseFilter` does not solve my issue. My filter is working fine **when it is called**. The problem is that `context.responseUnauthorized()` is not calling `CORSFilter` on response. – robinvrd Jul 20 '20 at 09:32
  • If JWTAuthenticationMechanism is called at the servlet container level, then it is before the request even gets to Jersey. If it is unauthorized, then it will never get to the Jersey Servlet. In this case, either make the CorsFilter a servlet filter or use your servlet container's CORS filter. Most have one already. You just need to configure it. – Paul Samsotha Aug 14 '20 at 13:23

0 Answers0