简体   繁体   English

Play框架和Deadbolt重定向onAuthFailure

[英]Play Framework and Deadbolt redirect onAuthFailure

I have implemented my own Authenticator from Play Framework and DeadboltHandler from Deadbolt. 我已经从Play Framework实现了自己的Authenticator,而从Deadbolt实现了DeadboltHandler。

Using the methods onUnauthorized respective onAuthFailure I can send users that are not logged in to the "login page" instead of the actual page they are trying to access. 使用各自的onUnauthorized onAuthFailure方法,我可以发送未登录到“登录页面”的用户,而不是他们尝试访问的实际页面。

However, instead of sending a user directly to the "login page", I want to specify what page the user should be sent to depending on which page the user tries to reach. 但是,不是要直接将用户发送到“登录页面”,而是要根据用户尝试访问的页面来指定应将用户发送到哪个页面。 For example, if the user tries to access /settings the user should be redirected to the login page. 例如,如果用户尝试访问/ settings,则应将其重定向到登录页面。 If the user tries to access /player/1 the user should be redirected to another page, say, "create user" page. 如果用户尝试访问/ player / 1,则应将用户重定向到另一个页面,例如“创建用户”页面。

I was hoping that there is some smart way to do this with annotations, something like: @someannotation(redirect = route/id) so I can redirect to the relevant route if the user is not logged in, else to the standard "login page". 我希望可以通过一些聪明的方法来使用注释,例如:@someannotation(redirect = route / id),这样,如果用户未登录,我可以重定向到相关的路由,否则可以重定向到标准的“登录”页面”。

Any one got any ideas? 任何人有任何想法吗?

Code snippet example for controller and route method: 控制器和路由方法的代码片段示例:

@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 example for DeadboltHandler onAuthFailure: 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);

There are a couple of different ways you can do this. 您可以通过两种不同的方法来执行此操作。

Approach 1: Repurpose the content value 方法1:重新利用content

In this approach, you can use the content value of the constraint annotations to give a hint to the handler. 在这种方法中,您可以使用约束注释的content值来提示处理程序。 You can use a class-level constraint to define the default redirect, eg go to the login page, and method-level constraints to override the default redirect. 您可以使用类级别的约束来定义默认重定向,例如转到登录页面,并使用方法级别的约束来覆盖默认重定向。 All constraints have the content value, I'm just using SubjectPresent as an example; 所有约束都具有content值,我SubjectPresent为例。 you can also mix constraints, eg have SubjectPresent at the class level and Restrict at the method level. 您还可以混合使用约束,例如,在类级别使用SubjectPresent ,在方法级别使用Restrict

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

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

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

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

In your DeadboltHandler implementation, you would then need a test on the content: 然后,在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);
}

Approach 2: Use the ROUTE_PATTERN tag 方法2:使用ROUTE_PATTERN标记

Instead of specifying keys in the constraint annotations, you can instead use the route specified in the request to determine the requested action. 您可以使用请求中指定的路由来确定所请求的操作,而不必在约束注释中指定键。

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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM