1

我正在尝试使用 Deadbolt 2 在 Play Framework 2.4.x 中实现一个简单的认证系统。

我遵循了 Chaloner 编写的本指南,并实现了我的 deadbolt 处理程序,如您在此处看到的:

public class MyDeadboltHandler extends AbstractDeadboltHandler {

    public F.Promise<Optional<Result>> beforeAuthCheck(Http.Context context) {
        // returning null means that everything is OK.  Return a real result if you want a redirect to a login page or
        // somewhere else
        return F.Promise.promise(Optional::empty);
    }

    public F.Promise<Optional<Subject>> getSubject(Http.Context context) {
        // in a real application, the user name would probably be in the session following a login process
        User user = new User("MyUser", "my.email@info.com");
        return F.Promise.promise(() -> Optional.ofNullable(user));
    }

    public F.Promise<Optional<DynamicResourceHandler>> getDynamicResourceHandler(Http.Context context) {
        return F.Promise.promise(() -> Optional.of(new MyDynamicResourceHandler()));
    }

    @Override
    public F.Promise<Result> onAuthFailure(final Http.Context context, final String content) {
        // you can return any result from here - forbidden, etc
        return F.Promise.promise(() -> Controller.redirect(routes.Application.index()));
    }
}

我的主要控制器是这样的:

public class Application extends Controller {

    public Result index() {
        return ok(index.render());
    }

    @SubjectPresent
    public Result denyAccess(){
        return ok(notAllowed.render());
    }

    public Result permitAccess(){
        return ok(allowed.render());
    }

    public Result errorPage(){
        return ok(errorPage.render());
    }
}

当我尝试访问 action 呈现的页面时出现问题denyAccess。在这种情况下,我在页面上得到一个 NullPointerException,没有我可以读取的堆栈跟踪,如下图所示。

在此处输入图像描述

即使我尝试访问控制器拒绝访问,似乎也从未调用过 onAuthFailure 方法。

你可以在我的 github 页面上看到完整的项目,它很短,我认为它可以帮助你理解问题。

谢谢您的帮助。

4

1 回答 1

1

问题在于您的实施HandlerCache

@Singleton
public class MyHandlerCache implements HandlerCache {

    private final Map<String, DeadboltHandler> handlers = new HashMap<>();

    public MyHandlerCache() {
        handlers.put("DEFAULT_KEY", new MyDeadboltHandler());
    }

    @Override
    public DeadboltHandler apply(final String key) {
        return handlers.get(key);
    }

    @Override
    public DeadboltHandler get() {
        return handlers.get("DEFAULT_KEY");
    }
}

默认情况下,默认处理程序键名称由定义,be.objectify.deadbolt.java.ConfigKeys.DEFAULT_HANDLER_KEY但在MyHandlerCache您使用"DEFAULT_KEY". 但是,当调用此方法时:

public DeadboltHandler apply(final String key) {
    return handlers.get(key);
}

它将be.objectify.deadbolt.java.ConfigKeys.DEFAULT_HANDLER_KEY作为键接收并返回 null。

我将确保更好地记录并在文档中明确说明。要修复您的实现,请替换"DEFAULT_KEY"be.objectify.deadbolt.java.ConfigKeys.DEFAULT_HANDLER_KEY

@Singleton
public class MyHandlerCache implements HandlerCache {

    private final Map<String, DeadboltHandler> handlers = new HashMap<>();

    public MyHandlerCache() {
        handlers.put(ConfigKeys.DEFAULT_HANDLER_KEY, new MyDeadboltHandler());
    }

    @Override
    public DeadboltHandler apply(final String key) {
        return handlers.get(key);
    }

    @Override
    public DeadboltHandler get() {
        return handlers.get(ConfigKeys.DEFAULT_HANDLER_KEY);
    }
}
于 2016-02-08T10:24:20.887 回答