2017-04-21 30 views
1

我已經實現了從呆播放框架和DeadboltHandler我自己的身份驗證。播放框架和重定向呆鎖onAuthFailure

使用方法onUnauthorized各自onAuthFailure我可以給未在到「登錄頁面」,而不是他們試圖訪問實際的頁面登錄的用戶。

然而,而不是直接發送到用戶的「登錄頁」,我想指定哪些頁面的用戶應該被送到取決於哪個頁面的用戶嘗試訪問。例如,如果用戶嘗試訪問/設置,則應將用戶重定向到登錄頁面。如果用戶試圖訪問/ player/1,用戶應該被重定向到另一個頁面,比如說「創建用戶」頁面。

我一直希望有一個帶註解做到這一點一些聰明的辦法,是這樣的:@someannotation(重定向=路徑/ ID),所以我可以重定向到相關的途徑,如果用戶沒有登錄,否則到標準的「登錄頁面」。

任何人有任何想法?

代碼片段例如對於控制器和路由方法:

@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() { 

代碼片段例如用於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); 

回答

1

有幾種不同的方法可以做到這一點。

方法1:重新利用content

在這種方法中,你可以使用約束註釋的content價值給予的提示,處理。您可以使用類級約束來定義默認重定向,例如轉到登錄頁面和方法級別的約束來覆蓋默認的重定向。所有約束都有content的值,我只是以SubjectPresent爲例;你也可以混合約束,例如在課程級別有SubjectPresent,在方法級別有Restrict

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

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

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

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

在你DeadboltHandler實現,你就那麼需要對內容的測試:

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); 
} 

方法2:在約束註釋使用ROUTE_PATTERN標籤

除了指定鍵,您可以改爲使用請求中指定的路由來確定請求的操作。

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

這看起來像我需要的,但是,它不適合我,至少不是現在。我使用的是舊版本的Deadbolt(它會在某些時候升級),並假設你的答案是後來(如果不是最新的)Deadbolt版本。我也意識到你是Deadbolt的作者,真棒! :)我AbstractDeadboltHandler的onAuthFailure方法是這樣的:F.Promise onAuthFailure(Http.Context背景下,字符串的內容)。 –

+0

我不明白的是我的「內容」參數總是顯得空虛。另外,我可以在方法層次同時使用註釋@CustomRestric(值= .​​..)和@SubjectPresent(含量= ...),我可以在控制器級別結合@DeferredDeadbolt和@SubjectPresent(含量=「CREATEUSER」) ? –

+0

我會用代碼片段更新我的文章,以便更容易地瞭解我的意思。 (請忽略我使用syso打印:D) –