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

2022-09-01 09:55:06

我正在使用身份验证/授权机制构建 rest 服务,如本教程中所述: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注释:

服务器应用程序:

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

安全接收器:

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

因为仅当基础由标准 JAX-RS 管道调用时(而不是从应用程序代码调用)时才调用 。ReaderInterceptorMessageBodyReader.readFrom

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

规范在 §6.5.2 中指出拦截器是全局注册的,除非用注释注释,但我不知道是否可以处理一个,如果它没有明确注册,如 RestEASY Interceptor Not Be Call 所示@Provider@NameBindingRESTEasy@ServerInterceptor


答案 2

如果您需要访问底层(就像您以前能够通过实现获得的那样),则可以执行以下操作:java.lang.reflect.MethodAcceptedByMethod

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