2017-04-21 3 views
1

DeadboltからPlay FrameworkとDeadboltHandlerから独自のAuthenticatorを実装しました。Play FrameworkとDeadbolt redirect onAuthFailure

認証されていないそれぞれのonAuthFailureのメソッドを使用して、ログインしようとしている実際のページの代わりにログインページにログインしていないユーザーを送信できます。

しかし、「ログインページ」に直接ユーザーを送信する代わりに、ユーザーがどのページに到達しようとしているかによってユーザーに送信するページを指定する必要があります。たとえば、ユーザーが/設定にアクセスしようとすると、ユーザーはログインページにリダイレクトされます。ユーザーが/ player/1にアクセスしようとすると、ユーザーは別のページにリダイレクトする必要があります。たとえば、「ユーザーを作成」ページです。

私はアノテーションでこれを行うためのスマートな方法があると期待していました。@someannotation(redirect = route/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です。あなたのDeadboltHandlerの実装で

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

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

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

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

、あなたは、コンテンツのテストが必要になります

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 context、String content)。 –

+0

私が得意でないのは、私の「コンテンツ」パラメータが常に空になっているようだということです。また、@CustomRestric(value = ...)と@SubjectPresent(content = ...)というアノテーションをメソッドレベルで使用することはできますか?コントローラレベルで@DeferredDeadboltと@SubjectPresent(content = "createuser")を組み合わせることはできますか? ? –

+0

ポストをコードスニペットで更新して、意味を理解しやすくします。 (私はsysoプリントを使用していることを無視してください:D) –