【问题标题】:Play Framework and Deadbolt redirect onAuthFailurePlay Framework 和 Deadbolt 重定向 onAuthFailure
【发布时间】:2017-09-18 03:25:38
【问题描述】:

我已经从 Play Framework 实现了自己的 Authenticator,从 Deadbolt 实现了 DeadboltHandler。

使用 onUnauthorized 和 onAuthFailure 方法,我可以将未登录的用户发送到“登录页面”,而不是他们尝试访问的实际页面。

但是,我不想将用户直接发送到“登录页面”,而是根据用户尝试访问的页面来指定应该将用户发送到哪个页面。例如,如果用户尝试访问 /settings,则应将用户重定向到登录页面。如果用户尝试访问 /player/1,则应将用户重定向到另一个页面,例如“创建用户”页面。

我希望有一些聪明的方法可以通过注释来做到这一点,例如:@someannotation(redirect = route/id) 这样如果用户未登录,我可以重定向到相关路由,否则重定向到标准“登录页面”。

有人有什么想法吗?

控制器和路由方法的代码sn-p示例:

@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 的代码 sn-p 示例:

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

【问题讨论】:

    标签: java playframework deadbolt


    【解决方案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);
    }
    

    方法二:使用 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
    }
    

    【讨论】:

    • 这看起来像我需要的,但是,它对我来说不太有效,至少现在不行。我正在使用较旧版本的 Deadbolt(它会在某个时候升级)并假设您的答案是针对较新版本的 Deadbolt(如果不是最新版本)。我还意识到你是 Deadbolt 的作者,太棒了! :) 我的 AbstractDeadboltHandler 的 onAuthFailure 方法如下所示:F.Promise onAuthFailure(Http.Context context, String content)。
    • 我不太明白的是我的“内容”参数似乎总是空的。另外,我可以在方法级别同时使用注解@CustomRestric(value = ...) 和@SubjectPresent(content = ...),我可以在控制器级别结合@DeferredDeadbolt 和@SubjectPresent(content = "createuser") ?
    • 我将使用代码 sn-p 更新我的帖子,以便更容易理解我的意思。 (请忽略我正在使用 syso print :D)
    • 我会仔细检查内容问题,但它应该可以正常工作。重写 F.Promise 应该很简单。组合这些注释是可能的。
    • 当我进入我设置的测试页面时没有任何中断。我像往常一样被重定向到我的登录页面。内容参数似乎是空的。但是,我也注意到我收到了一些错误消息,即:[error] b.o.d.j.u.RequestUtils - Error getting subject: nulljava.lang.NullPointerException: null[error] b.o.d.j.a.AbstractDeadboltAction - Access to [/settings] requires a subject, but no subject is present.
    猜你喜欢
    • 2016-01-01
    • 2016-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多