2013-07-11 7 views
27

Ich Aufbau Rest Dienst eines Authentifizierungs-/Autorisierungsmechanismus, wie in dieser Anleitung beschrieben: http://howtodoinjava.com/2013/06/26/jax-rs-resteasy-basic-authentication-and-authorization-tutorial/Was ist der richtige Ersatz für den Rasteasy 3.X PreProcessInterceptor?

Grundsätzlich verwendet es die PreProcessInterceptor Schnittstelle, um die Zielmethode für Annotationen zu scannen (von javax.annotation.security Paket), das die erforderlichen Rollen Zugriffe beschreiben diese Methode. Da der Authentifikator hier ein Interceptor ist, kann er den Aufruf der Zielmethode abbrechen und bei Bedarf eine 401 (nicht autorisiert) zurückgeben.

Das Problem hier ist, dass die Schnittstelle org.jboss.resteasy.spi.interception.PreProcessInterceptor in der aktuellen RestEasy-Version (3.0.1) veraltet ist, und ich habe Probleme, das gleiche Verhalten mit dem Standard zu implementieren JAX-RS-Schnittstellen.

Ich benutze die javax.ws.rs.ext.ReaderInterceptor-Schnittstelle, um den Anruf abzufangen. Aber irgendwie ruft der Server es nie an: der Abfangjäger wird einfach ignoriert.

Ich Registrierung der Abfangjäger/Ressourcen die gleiche Art und Weise, wie ich mit dem ehemaligen PreProcessInterceptor getan hat, und mit dem gleichen @Provider und @ServerInterceptor Anmerkungen:

Serveranwendung:

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

Irgendwelche Erkenntnisse darüber, wie ich dieses Problem lösen kann?

Vielen Dank.

+2

Das vollständige Beispiel in einem anderen Beitrag aktualisiert: http://howtodoinjava.com/2013/07/25/jax-rs-2-0-restasy-3-0-2-final-security-tutorial/ – lokesh

Antwort

25

RESTEasy 3.x.x entspricht der JAX-RS 2.0 Spezifikation.

Was Sie versuchen könnte zu tun, erreicht werden (vielleicht besser) mit:

@Provider 
public class SecurityInterceptor 
     implements javax.ws.rs.container.ContainerRequestFilter { 
    @Override 
    public void filter(ContainerRequestContext requestContext){ 
     if (not_authenticated){ requestContext.abortWith(response)}; 
    } 
} 

seit dem ReaderInterceptor aufgerufen wird nur, wenn der Basiswert MessageBodyReader.readFrom durch die Standard-JAX-RS-Pipeline genannt wird, nicht Anwendungscode fromthe .

Der Grund, warum Ihr Interceptor nicht aufgerufen wird, könnte die @ServerInterceptor Annotation sein, die eine RESTEasy-Erweiterung ist.

Die Spezifikation Zustände bei §6.5.2, dass ein Abfangjäger global registriert ist, es sei denn, die @Provider mit einer @NameBinding Anmerkung kommentiert wird, aber ich weiß nicht, ob RESTEasy ein @ServerInterceptor umgehen kann, wenn es nicht explizit in RestEASY Interceptor Not Being Called wie gezeigt registriert ist

+0

Wie kann ich mit dem ContainerRequestFilter die Annotationen der Zielmethode erhalten? Der Filter/Interceptor muss basierend auf den Benutzerrollen wissen, dass der Aufruf ordnungsgemäß zugelassen oder verweigert wird. –

+0

'ContainerRequestFilter.getUriInfo(). GetMatchedResources()' gibt die Liste der übereinstimmenden Ressourcenobjekte zurück. Dort können Sie die Annotationen analysieren, die den tatsächlich aufgerufenen Methoden entsprechen. –

+1

Ich glaube, Sie meinten 'requestContext.getUriInfo(). GetMatchedResources()'. Wie auch immer, diese Methode ist nicht so einfach zu benutzen wie im früheren 'PreProcessInterceptor', da ich keinen direkten Zugriff auf das Ziel' java.lang.reflect.Method' habe. Aber ich werde die Antwort als akzeptiert markieren, da sie das Problem löst. –

4

Wenn Sie benötigen, um Zugriff auf das bekommen zugrunde liegenden java.lang.reflect.Method (wie Sie verwendet der Lage sein, durch zu bekommen AcceptedByMethod Implementierung), können Sie folgendes tun:

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

Wie erhalten Sie eine httpRequest von RequestContext. Ich habe eine Anforderung, den InputStream von httpRequest zu lesen. Wie geht das? Oder ist ein Weg dorthin kann ich InputStream aus dem containerrequestcontext erhalten? – arunsankarkk

+0

Ich bekomme NULL-Referenz von methodInvoker, weiß nicht warum. –

2

ich wollte auch den Zugang zum u erhalten nderlying java.lang.reflect.Method und versucht mtptyps Antwort mit Reseasy 3.0.8, aber das war Null auf den getProperty Aufruf zurück. Ich benutze auch Spring und Resteasy-Frühling, obwohl ich nicht glaube, dass dies überhaupt Auswirkungen haben sollte.

Wenn Sie in meine Situation laufen und ein Post Matching ContainerRequestFilter implementieren (Sie müssen, wenn Sie erwarten, die Matched-Ressource-Methode sowieso zu bekommen) dann können Sie tatsächlich die ContainerRequestContext auf die Implementierung Rasteasy hat für die Post Match-Szenario. Die PostMatchContainerRequestContext hat einen Verweis auf den ResourceMethodInvoker.

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

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

    /* rest of code here */ 
} 
Verwandte Themen