什么是Resteasy 3.X PreProcessInterceptor的正确替代品?

时间:2013-07-11 13:37:50

标签: java rest jax-rs resteasy

我正在使用本教程中描述的身份验证/授权机制构建休息服务:http://howtodoinjava.com/2013/06/26/jax-rs-resteasy-basic-authentication-and-authorization-tutorial/

基本上它使用PreProcessInterceptor接口扫描目标方法的注释(来自javax.annotation.security包),该方法描述了访问该方法所需的角色。由于此处的验证器是拦截器,它可以取消目标方法调用,如果需要,返回401(未授权)。

这里的问题是在当前的RestEasy版本(3.0.1)中不推荐使用接口org.jboss.resteasy.spi.interception.PreProcessInterceptor,我在尝试使用标准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...
     }
}

有关如何解决此问题的任何见解?

谢谢。

3 个答案:

答案 0 :(得分:26)

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)};
     }
}

因为仅当标准JAX-RS管道调用基础ReaderInterceptor而不是应用程序代码调用MessageBodyReader.readFrom时才会调用@ServerInterceptor

但是,未调用拦截器的原因可能是@Provider注释,这是一个RESTEasy扩展。

规范在§6.5.2中声明拦截器是全局注册的,除非@NameBinding注释了RESTEasy注释,但我不知道@ServerInterceptor是否可以处理如果{{1}}

中没有明确注册{{1}},则为{{1}}

答案 1 :(得分:4)

如果您需要访问基础java.lang.reflect.Method(就像您以前通过实施AcceptedByMethod所获得的那样),您可以执行以下操作:

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

答案 2 :(得分:3)

我还希望能够访问底层的java.lang.reflect.Method并尝试使用Resteasy 3.0.8的mtpettyp答案,但是在getProperty调用中返回null。我也在使用Spring和resteasy-spring,虽然我不认为这会影响到这一点。

如果遇到我的情况并且正在实现匹配ContainerRequestFilter(如果您希望获得匹配的资源方法,那么您必须这样做),那么您实际上可以将ContainerRequestContext转换为Resteasy在Post Match场景中的实现。 PostMatchContainerRequestContext引用了ResourceMethodInvoker。

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

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

    /* rest of code here */
}