31

このチュートリアルで説明されているように、認証/承認メカニズムを使用して残りのサービスを構築しています: 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 アノテーションを使用しています。

サーバーアプリケーション:

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

この問題を解決するにはどうすればよいかについての洞察はありますか?

ありがとうございました。

4

3 に答える 3

29

RESTEasy 3.xx は 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は、RESTEasy 拡張機能であるアノテーションである可能性があります。

仕様では、§6.5.2 で@Provider、アノテーションが付けられていない限り、インターセプターはグローバルに登録されていると述べていますが、 RestEASY Interceptor Not Being Calledに示すように、明示的に登録されていない場合にa を処理できる@NameBindingかどうかはわかりませんRESTEasy@ServerInterceptor

于 2013-07-11T15:41:18.520 に答える
4

基になるものにアクセスする必要がある場合java.lang.reflect.Method(以前は を実装することでアクセスできたようにAcceptedByMethod)、次のことができます。

ResourceMethodInvoker methodInvoker = (ResourceMethodInvoker) 
            requestContext.getProperty("org.jboss.resteasy.core.ResourceMethodInvoker");
Method method = methodInvoker.getMethod();
于 2013-11-26T16:54:15.360 に答える
3

また、基になるものへのアクセスを取得したかったのでjava.lang.reflect.Method、Resteasy 3.0.8 で mtpettyp の回答を試しましたが、getProperty 呼び出しで null が返されました。Spring と resteasy-spring も使用していますが、これが影響を与えるとはまったく思いません。

私の状況に遭遇し、Post Matching を実装しているContainerRequestFilter場合 (とにかく一致したリソース メソッドを取得することを期待していた場合は、そうしなければなりません)、ContainerRequestContextResteasy が Post Match シナリオ用に持っている実装にキャストすることができます。PostMatchContainerRequestContextには、ResourceMethodInvoker への参照があります。

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

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

    /* rest of code here */
}
于 2014-05-16T16:30:10.223 に答える