I'm building rest service using an authentication/authorization mechanism as described in this tutorial: http://howtodoinjava.com/2013/06/26/jax-rs-resteasy-basic-authentication-and-authorization-tutorial/
Basically it uses the PreProcessInterceptor interface to scan the target method for annotations (from javax.annotation.security package) which describe the required roles to access that method. As the the authenticator here is an interceptor, it can cancel the target method invocation, returning a 401 (unauthorized) if needed.
The problem here is that the interface org.jboss.resteasy.spi.interception.PreProcessInterceptor is deprecated in the current RestEasy version (3.0.1), and I'm having problems trying to implement the same behaviour with the standard JAX-RS interfaces.
I'm using the javax.ws.rs.ext.ReaderInterceptor interface to intercept the call. But somehow the server never calls it: the interceptor is just ignored.
I'm registering the interceptors/resources the same way as I did with the former PreProcessInterceptor, and using the same @Provider and @ServerInterceptor annotations:
ServerApplication:
public class ServerApplication extends javax.ws.rs.core.Application {
private final HashSet<Object> singletons = new LinkedHashSet<Object>();
public ServerApplication() {
singletons.add(new SecurityInterceptor());
singletons.add( ... ); //add each of my rest resources
}
@Override
public Set<Class<?>> getClasses() {
HashSet<Class<?>> set = new HashSet<Class<?>>();
return set;
}
@Override
public Set<Object> getSingletons() {
return singletons;
}
}
SecurityInterceptor:
@Provider
@ServerInterceptor
public class SecurityInterceptor implements javax.ws.rs.ext.ReaderInterceptor {
@Override
public Object aroundReadFrom(ReaderInterceptorContext context){
//code that is never called... so lonely here...
}
}
Any insights about how can I solve this problem?
Thank you.
RESTEasy 3.x.x conforms to the JAX-RS 2.0 specification.
What you are trying to do could be accomplished (maybe better) with:
@Provider
public class SecurityInterceptor
implements javax.ws.rs.container.ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestContext){
if (not_authenticated){ requestContext.abortWith(response)};
}
}
since the ReaderInterceptor
is invoked only if the underlying MessageBodyReader.readFrom
is called by the standard JAX-RS pipeline, not fromthe application code.
The reason why your interceptor is not called, though, could be the @ServerInterceptor
annotation, which is a RESTEasy extension.
The spec states at §6.5.2 that a interceptor is globally registered, unless the @Provider
is annotated with a @NameBinding
annotation, but I don't know if RESTEasy
can handle a @ServerInterceptor
if it's not explicitly registered as shown in RestEASY Interceptor Not Being Called