2013-07-11 3 views
27

Я строй службы отдыха с использованием механизма аутентификации/авторизации, как описано в данном руководстве: http://howtodoinjava.com/2013/06/26/jax-rs-resteasy-basic-authentication-and-authorization-tutorial/Какая надлежащая замена Resteasy 3.X PreProcessInterceptor?

В основном он использует интерфейс 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... 
    } 
} 

Любая информация о том, как решить эту проблему?

спасибо.

+2

Обновленный полный пример в другом посте: http://howtodoinjava.com/2013/07/25/jax-rs-2-0-resteasy-3-0-2-final-security-tutorial/ – lokesh

ответ

25

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, не FROMTHE код приложения ,

Причина, по которой ваш перехватчик не вызывается, может быть аннотацией @ServerInterceptor, которая является расширением RESTEasy.

спецификации состояний в §6.5.2, что перехватчик глобально зарегистрированных, если @Provider не аннотированный с @NameBinding аннотацию, но я не знаю, если RESTEasy может обрабатывать @ServerInterceptor, если это явно не зарегистрирован, как показано на RestEASY Interceptor Not Being Called

+0

Использование ContainerRequestFilter, как я могу получить аннотации целевого метода? Фильтр/перехватчик должен знать, что правильно разрешить или запретить вызов, на основе ролей пользователя. –

+0

'ContainerRequestFilter.getUriInfo(). GetMatchedResources()' возвращает список объектов соответствующих объектов. Там вы можете разобрать аннотации, соответствующие действительным вызываемым методам. –

+1

Я думаю, что вы имели в виду 'requestContext.getUriInfo(). GetMatchedResources()'. Во всяком случае, этот метод не так прост в использовании, как в предыдущем «PreProcessInterceptor», так как у меня нет прямого доступа к целевому «java.lang.reflect.Method'. Но я буду отмечать ответ как принятый, так как он решает проблему. –

4

Если вам необходимо получить доступ к основной java.lang.reflect.Method (как вы использовали, чтобы иметь возможность получить за счет внедрения AcceptedByMethod), вы можете сделать следующее:

ResourceMethodInvoker methodInvoker = (ResourceMethodInvoker) 
      requestContext.getProperty("org.jboss.resteasy.core.ResourceMethodInvoker"); 
Method method = methodInvoker.getMethod(); 
+1

Как получить httpRequest из requestContext. У меня есть требование прочитать InputStream из httpRequest. как это сделать? Или это способ, которым я могу получить InputStream из containerrequestcontext? – arunsankarkk

+0

Я получаю нулевую ссылку от методаInvoker, не знаю почему. –

2

Я также хотел бы получить доступ к и- nderlying java.lang.reflect.Method и попробовал ответ mtpettyp с Resteasy 3.0.8, но это возвращало null на вызов getProperty. Я также использую Spring и resteasy-spring, хотя я не считаю, что это должно повлиять на это вообще.

Если вы столкнулись с моей ситуацией и используете Post Matching ContainerRequestFilter (вы вроде бы должны, если бы ожидали получить метод согласованных ресурсов в любом случае), тогда вы можете фактически наложить ContainerRequestContext на реализацию Resteasy для публикации Сценарий соответствия. PostMatchContainerRequestContext имеет ссылку на ResourceMethodInvoker.

public void filter(ContainerRequestContext context) throws IOException { 
    PostMatchContainerRequestContext pmContext = (PostMatchContainerRequestContext) context; 

    Method method = pmContext.getResourceMethod().getMethod(); 

    /* rest of code here */ 
} 
Смежные вопросы