2017-04-21 1 views
1

Ich habe meinen eigenen Authenticator von Play Framework und DeadboltHandler von Deadbolt implementiert.Play Framework und Deadbolt Redirect onAuthFailure

Mit den Methoden onUnauthorized bzw. onAuthFailure kann ich nicht eingeloggte Benutzer auf die "Login-Seite" anstatt auf die eigentliche Seite, auf die sie zugreifen wollen, schicken.

Anstatt jedoch einen Benutzer direkt auf die "Anmeldeseite" zu senden, möchte ich angeben, auf welcher Seite der Benutzer gesendet werden soll, je nachdem, welche Seite der Benutzer erreichen möchte. Wenn der Benutzer beispielsweise versucht, auf Einstellungen zuzugreifen, sollte der Benutzer zur Anmeldeseite umgeleitet werden. Wenn der Benutzer versucht, auf/player/1 zuzugreifen, sollte der Benutzer auf eine andere Seite umgeleitet werden, beispielsweise die Seite "Benutzer erstellen".

Ich hatte gehofft, dass es eine kluge Möglichkeit gibt, dies mit Anmerkungen zu tun, etwa: @someannotation (redirect = route/id), also kann ich auf die entsprechende Route umleiten, wenn der Benutzer nicht eingeloggt ist Standard "Login-Seite".

Hat jemand irgendwelche Ideen?

Code-Snippet Beispiel für Steuerung und Routenmethode:

@Security.Authenticated(Secured.class) 
@SubjectPresent(content = "createuser") 
@DeferredDeadbolt 
public class Settings extends Controller { 

    @SubjectPresent(content = "login") 
    @CustomRestrict(value = { @RoleGroup({ UserRole.player}), @RoleGroup(UserRole.server_owner) }) 
    public static Result settings() { 

Code-Snippet Beispiel für DeadboltHandler onAuthFailure:

@Override 
    public F.Promise<Result> onAuthFailure(Http.Context context, String content) { 
     return F.Promise.promise(new F.Function0<Result>() { 
      @Override 
      public Result apply() throws Throwable { 
       System.out.println(content); 

Antwort

1

Es gibt ein paar verschiedene Möglichkeiten, wie Sie dies tun können.

Ansatz 1: Repurpose den content Wert

Bei diesem Ansatz Sie den content Wert der Einschränkung Anmerkungen können einen Hinweis auf die Handler zu geben. Sie können eine Einschränkung auf Klassenebene verwenden, um die Standardumleitung zu definieren, z. Wechseln Sie zur Anmeldeseite und beschränken Sie auf Methodenebene die Standardumleitung. Alle Einschränkungen haben den content Wert, ich verwende nur SubjectPresent als ein Beispiel; Sie können auch Einschränkungen mischen, z. haben Sie auf Klassenebene und auf Methodenebene Restrict.

@SubjectPresent(content = "login") 
public class FooController extends Controller { 

    public Result settings() { 
     // ... 
    } 

    public Result somethingElse() { 
     // ... 
    } 

    @SubjectPresent(content = "create-user") 
    public Result viewUser() { 
     // ... 
    } 
} 

In Ihrer DeadboltHandler Implementierung, würden Sie dann benötigen einen Test auf dem Inhalt:

public CompletionStage<Result> onAuthFailure(final Http.Context context, 
              final Optional<String> content) { 
    return CompletableFuture.supplyAsync(() -> content.map(redirectKey -> { 
     final Result result; 
     if ("login".equals(redirectKey)) { 
      result = [redirect to login action] 
     } 
     else if ("create-user".equals(redirectKey)) { 
      result = [redirect to create user action] 
     } else { 
      result = [redirect to default authorization failure action] 
     } 
    }).orElseGet(() -> [redirect to default authorization failure action]), executor); 
} 

Ansatz 2: Verwenden Sie den ROUTE_PATTERN Tag

Statt Angabe Schlüssel in den Constraint Annotationen Sie können stattdessen die in der Anfrage angegebene Route verwenden, um die angeforderte Aktion zu bestimmen.

public CompletionStage<Result> onAuthFailure(final Http.Context context, 
              final Optional<String> content) { 
    final String route = requestHeader.tags().get(Router.Tags.ROUTE_PATTERN); 
    // examine the route and work out what you want to do 
} 
+0

Das sieht aus, was ich brauche, aber es funktioniert nicht ganz für mich, zumindest jetzt nicht. Ich benutze eine ältere Version von Deadbolt (es wird irgendwann aktualisiert) und nehme an, dass deine Antwort für eine spätere (wenn nicht die letzte) Version von Deadbolt ist. Ich erkannte auch, dass du der Autor von Deadbolt bist, großartige Arbeit! :) Die onAuthFailure-Methode von AbstractDeadboltHandler sieht folgendermaßen aus: F.Promise onAuthFailure (Http.Context-Kontext, String-Inhalt). –

+0

Was ich nicht ganz verstehe, ist, dass mein "content" -Parameter immer leer zu sein scheint. Kann ich auch die Annotationen @CustomRestric (Wert = ...) und @SubjectPresent (Inhalt = ...) auf Methodenebene verwenden, und kann ich @DeferredDeadbolt und @SubjectPresent (content = "createuser") auf Controller-Ebene kombinieren ? –

+0

Ich werde meinen Beitrag mit einem Code-Snippet aktualisieren, so dass es einfacher ist zu sehen, was ich meine. (Bitte ignorieren Sie, dass ich syso print verwende: D) –