2013-07-11 34 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(未授權)。

這裏的問題是,在當前的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... 
    } 
} 

有關如何解決此問題的任何見解?

謝謝。

+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的是,如圖中RestEASY Interceptor Not Being Called一個攔截器在全球範圍內註冊,除非@Provider@NameBinding註解,但我不知道是否能RESTEasy處理@ServerInterceptor,如果它沒有明確登記的規範狀態

+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

如何從requestContext獲取httpRequest。我有要求從httpRequest讀取InputStream。如何做到這一點?或者,我可以從containerrequestcontext獲取InputStream嗎? – arunsankarkk

+0

我從methodInvoker獲得null引用,不知道爲什麼。 –

2

我還希望自己能訪問到U nderlying java.lang.reflect.Method並嘗試使用Resteasy 3.0.8 mtpettyp的答案,但是getProperty調用返回null。我也使用Spring和resteasy-spring,儘管我不相信這會影響到這一切。

如果您碰到我的情況並正在實施匹配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 */ 
} 
相關問題