Какая надлежащая замена Resteasy 3.X PreProcessInterceptor?
Я создаю службу отдыха с использованием механизма аутентификации/авторизации, как описано в этом уроке: http://howtodoinjava.com/2013/06/26/jax-rs-resteasy-basic-authentication-and-authorization-tutorial/
В основном он использует интерфейс PreProcessInterceptor для сканирования целевого метода аннотаций (из javax.annotation.security), которые описывают требуемые роли для доступа к этому методу. Поскольку аутентификатор здесь является перехватчиком, он может отменить вызов целевого метода, возвращая при необходимости 401 (неавторизованный).
Проблема в том, что интерфейс org.jboss.resteasy.spi.interception.PreProcessInterceptor устарел в текущей версии RestEasy (3.0.1), и у меня возникают проблемы с попыткой реализовать то же поведение со стандартным JAX -RS.
Я использую интерфейс javax.ws.rs.ext.ReaderInterceptor для перехвата вызова. Но почему-то сервер никогда не называет его: перехватчик просто игнорируется.
Я регистрирую перехватчики/ресурсы так же, как и с предыдущим PreProcessInterceptor, и используя те же @Provider и @ServerInterceptor аннотации:
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...
}
}
Любые идеи о том, как я могу решить эту проблему?
Спасибо.
Ответы
Ответ 1
RESTEasy 3.x.x соответствует спецификации JAX-RS 2.0.
То, что вы пытаетесь сделать, может быть выполнено (возможно, лучше) с помощью
@Provider
public class SecurityInterceptor
implements javax.ws.rs.container.ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestContext){
if (not_authenticated){ requestContext.abortWith(response)};
}
}
поскольку ReaderInterceptor
вызывается только в том случае, если базовый MessageBodyReader.readFrom
вызывается стандартным конвейером JAX-RS, а не кодом приложения.
Причина, по которой ваш перехватчик не вызывается, может быть аннотацией @ServerInterceptor
, которая является расширением RESTEasy.
Спецификация заявляет в п. 6.5.5, что перехватчик зарегистрирован глобально, если только @Provider
не аннотация с аннотацией @NameBinding
, но я не знаю, может ли RESTEasy
обрабатывать @ServerInterceptor
, если это явно не зарегистрированный, как показано в Неактуальный перехватчик невосприимчивости
Ответ 2
Если вам нужно получить доступ к базовому java.lang.reflect.Method
(например, вы использовали для реализации через AcceptedByMethod
), вы можете сделать следующее:
ResourceMethodInvoker methodInvoker = (ResourceMethodInvoker)
requestContext.getProperty("org.jboss.resteasy.core.ResourceMethodInvoker");
Method method = methodInvoker.getMethod();
Ответ 3
Я также хотел получить доступ к базовому java.lang.reflect.Method
и попытался ответить mtpettyp с помощью Resteasy 3.0.8, но это возвращало null на вызов getProperty. Я также использую Spring и resteasy- spring, хотя я не считаю, что это должно повлиять на это вообще.
Если вы столкнулись с моей ситуацией и реализуете Post Matching ContainerRequestFilter
(вам нужно, если бы вы ожидали получить метод согласованных ресурсов в любом случае), вы можете фактически применить ContainerRequestContext
к реализации. Restaasy имеет для сценария Post Match. PostMatchContainerRequestContext имеет ссылку на ResourceMethodInvoker.
public void filter(ContainerRequestContext context) throws IOException {
PostMatchContainerRequestContext pmContext = (PostMatchContainerRequestContext) context;
Method method = pmContext.getResourceMethod().getMethod();
/* rest of code here */
}