2014-01-09 4 views
6

Ich entwickle eine REST-API mit RESTEasy mit Guice und im Moment versuche ich die Basisauthentifizierung mit Hilfe einer Annotation zu integrieren, die der @Auth in Dropwizard ähnlich ist. MitPrincipal in Resource-Methode in RESTEasy injizieren mit Guice

@Path("hello") 
public class HelloResource { 
    @GET 
    @Produces("application/json") 
    public String hello(@Auth final Principal principal) { 
     return principal.getUsername(); 
    } 
} 

der Hallo-Ressource Aufruf sollte von einigem Code der Ausführung von grundlegender Authentifizierung mit den Anmeldeinformationen im Header Authorization HTTP-Anforderung weitergegeben abgefangen werden und bei Erfolg den Haupt in das Verfahren Hauptparameter zu injizieren. Ich möchte auch in der Lage sein, eine Liste zulässiger Rollen an die Anmerkung zu übergeben, z. @Auth("admin").

Ich brauche wirklich einen Rat in welche Richtung zu gehen, um dies zu erreichen?

Antwort

7

Ich denke, Ihre beste Wette wäre die Verwendung eines Zwischenwerts im Anforderungsbereich. Unter der Annahme, dass Sie HelloResource nicht im Singleton-Bereich abgelegt haben, können Sie diesen Zwischenwert in eine Implementierung von ContainerRequestFilter und in Ihre Ressource injizieren, und Sie können ihn innerhalb dieser ContainerRequestFilter Implementierung mit allen erforderlichen Authentifizierungs- und Autorisierungsinformationen füllen.

Es wird wie folgt aussehen:

// Authentication filter contains code which performs authentication 
// and possibly authorization based on the request 
@Provider 
public class AuthFilter implements ContainerRequestFilter { 
    private final AuthInfo authInfo; 

    @Inject 
    AuthFilter(AuthInfo authInfo) { 
     this.authInfo = authInfo; 
    } 

    @Override 
    public void filter(ContainerRequestContext requestContext) throws IOException { 
     // You can check request contents here and even abort the request completely 
     // Fill authInfo with the data you need 
     Principal principal = ...; // Ask some other service possibly 
     authInfo.setPrincipal(principal); 
    } 
} 

@Path("hello") 
public class HelloResource { 
    private final AuthInfo authInfo; 

    @Inject 
    HelloResource(AuthInfo authInfo) { 
     this.authInfo = authInfo; 
    } 

    @GET 
    @Produces("application/json") 
    public String hello() { 
     // authInfo here will be pre-filled with the principal, assuming 
     // you didn't abort the request in the filter 
     return authInfo.getPrincipal().getUsername(); 
    } 
} 

public class MainModule extends AbstractModule { 
    @Override 
    protected void configure() { 
     bind(AuthFilter.class); 
     bind(HelloResource.class); 
     bind(AuthInfo.class).in(RequestScoped.class); 
    } 
} 

Und selbst wenn Sie die Ressource (oder sogar die Filter) in Singleton Umfang aus irgendeinem Grunde gelegt haben, kann man immer Provider<AuthInfo> statt AuthInfo injiziert.

aktualisieren

Es scheint, dass ich standardmäßig ist der Filter nicht in Singleton Umfang, dass etwas nicht in Ordnung war. Tatsächlich scheint es sich wie ein Singleton zu verhalten, obwohl es nicht als solches gebunden ist. Es wird beim Start des JAX-RS-Containers erstellt. Daher müssen Sie Provider<AuthInfo> in den Filter injizieren. Tatsächlich wird der Start des Containers fehlschlagen, wenn AuthInfo direkt in den Filter injiziert wird, während er an den Geltungsbereich gebunden ist. Ressource (wenn nicht explizit als Singleton gebunden) wird jedoch mit direkter Injektion in Ordnung sein.

Ich habe Arbeitsprogramm auf github hochgeladen.

+0

Danke! Hatte gehofft, dass es einen Weg gibt, den Principal direkter in die Resource-Methode zu injizieren, aber denke, ich muss diese Idee aufgeben;) Wenn ich deinen Code ausprobiere, wurde der Principal der Auth-Info nicht gesetzt, wenn meine Resource-Methode ist hingerichtet. Ich frage mich, was ich verpasst habe ... – Stine

+0

Ich schätze, ich sollte eine neue Frage bezüglich meiner Probleme mit der Erstellung einer Authentifizierungsanfrage stellen. – Stine

+0

@Stine, bitte beachten Sie mein Update) Sie waren schneller durch zweite Fraktionen :) –