Deadbolt 2 和 Play 2.4.x:无法访问的页面出现空指针异常
Deadbolt 2 and Play 2.4.x: Null pointer exception on unaccessible pages
我正在尝试在 Play Framework 2 中实现一个简单的身份验证系统。4.x 使用 Deadbolt 2。
我遵循了 Chaloner 编写的这篇 guide 并且我已经实现了我的门栓处理程序,正如您在此处看到的那样:
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());
}
}
当我尝试访问由操作 denyAccess
呈现的页面时出现问题。在这种情况下,我在页面上得到了一个 NullPointerException,但没有我可以读取的堆栈跟踪,如下图所示。
即使我尝试访问控制器 denyAccess,似乎也从未调用过 onAuthFailure 方法。
你可以在我的github页面上看到完整的项目here,它很短,我认为它可以帮助你理解问题。
感谢您的帮助。
问题出在你实现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
作为键和 return 空值。
我会确保更好地记录并在文档中明确说明。要修复您的实现,请将 "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);
}
}
我正在尝试在 Play Framework 2 中实现一个简单的身份验证系统。4.x 使用 Deadbolt 2。
我遵循了 Chaloner 编写的这篇 guide 并且我已经实现了我的门栓处理程序,正如您在此处看到的那样:
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());
}
}
当我尝试访问由操作 denyAccess
呈现的页面时出现问题。在这种情况下,我在页面上得到了一个 NullPointerException,但没有我可以读取的堆栈跟踪,如下图所示。
即使我尝试访问控制器 denyAccess,似乎也从未调用过 onAuthFailure 方法。
你可以在我的github页面上看到完整的项目here,它很短,我认为它可以帮助你理解问题。
感谢您的帮助。
问题出在你实现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
作为键和 return 空值。
我会确保更好地记录并在文档中明确说明。要修复您的实现,请将 "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);
}
}