Подтвердить что ты не робот

Какая надлежащая замена 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...
     }
}

Любые идеи о том, как я могу решить эту проблему?

Спасибо.

4b9b3361

Ответ 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 */
}