在 playframework 中拦截请求并检查授权
Intercept request and check authorization in playframework
我正在使用 play framework 2.4.2
和 Java,我想通过拦截所有请求并检查是否设置了 session 值来验证用户是否已登录。所以我扩展了 DefaultHttpRequestHandler 并覆盖了 createAction
方法来拦截所有请求。但是,我还没有找到验证 session.
的好方法
选项 1 - 失败
当我尝试获取 session 值时,出现运行时异常:There is no HTTP Context available from here
下面是我正在使用的class:
public class RequestHandler extends DefaultHttpRequestHandler {
@Override
public Action createAction(Http.Request request, Method method) {
session("loggedIn"); // Throws runtime Exception: no HTTP Context
}
}
选项 2 - 丑
由于 session 在技术上是一个 cookie,我可以使用如下代码从 header 中检索值:
for(String cookie : request.headers().get("Cookie")){
System.out.println("cookie: "+cookie);
}
但是我必须解析看起来像下一行的 cookie 字符串来获取登录值。对我来说太脏了。
_ga=GA1.1.1508004144.1421266376; ki_r=; ki_t=1438789543788%378129908%3B1438789543788%3B1%3B1; PLAY_SESSION=0570411c3eb55ad230681539ddcfaa4220583fd-loggedIn=1
选项 3 - 太容易忘记注释
我注意到一些网站记录了不同的方法,而是创建了一个
action composition 并为每个控制器 class 或方法添加适当的注解。
这种方法的问题是它需要开发人员记住添加注释。我更愿意将其反转以默认阻止每条路由,然后为不需要验证的路由添加注释。
记录动作组合的几个网站:
- http://alexgaribay.com/2014/06/16/authentication-in-play-framework-using-java/
- https://www.playframework.com/documentation/2.2.1/JavaGuide4
问题
有没有办法全局验证用户是否应该有权访问页面以及如何获取 session 变量?
*请注意,我对使用第三方插件进行身份验证不感兴趣。
即使我会重新考虑使用动作合成,你也可以修正选项 1。
创建自定义注释来标记不需要验证的操作。
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface NoAuthRequired {}
然后更改您的 HttpRequestHandler 实现。
public class RequestHandler extends DefaultHttpRequestHandler {
@Override
public Action createAction(Http.Request request, Method actionMethod) {
return new Action.Simple() {
@Override
public F.Promise<Result> call(Http.Context ctx) throws Throwable {
// if the action is annotated with @NoAuthRequired or user is logged in delegate to it
if (actionMethod.isAnnotationPresent(NoAuthRequired.class) || ctx.session().containsKey("loggedIn")) {
return delegate.call(ctx);
}
// otherwise, block access
else {
return F.Promise.pure(forbidden("You're not allowed"));
}
}
};
}
}
这样,除非明确注释,否则每条路线都需要验证。
从代码中可以看出,会话是通过上下文访问的。
我正在使用 play framework 2.4.2
和 Java,我想通过拦截所有请求并检查是否设置了 session 值来验证用户是否已登录。所以我扩展了 DefaultHttpRequestHandler 并覆盖了 createAction
方法来拦截所有请求。但是,我还没有找到验证 session.
选项 1 - 失败
当我尝试获取 session 值时,出现运行时异常:There is no HTTP Context available from here
下面是我正在使用的class:
public class RequestHandler extends DefaultHttpRequestHandler {
@Override
public Action createAction(Http.Request request, Method method) {
session("loggedIn"); // Throws runtime Exception: no HTTP Context
}
}
选项 2 - 丑
由于 session 在技术上是一个 cookie,我可以使用如下代码从 header 中检索值:
for(String cookie : request.headers().get("Cookie")){
System.out.println("cookie: "+cookie);
}
但是我必须解析看起来像下一行的 cookie 字符串来获取登录值。对我来说太脏了。
_ga=GA1.1.1508004144.1421266376; ki_r=; ki_t=1438789543788%378129908%3B1438789543788%3B1%3B1; PLAY_SESSION=0570411c3eb55ad230681539ddcfaa4220583fd-loggedIn=1
选项 3 - 太容易忘记注释
我注意到一些网站记录了不同的方法,而是创建了一个
action composition 并为每个控制器 class 或方法添加适当的注解。
这种方法的问题是它需要开发人员记住添加注释。我更愿意将其反转以默认阻止每条路由,然后为不需要验证的路由添加注释。
记录动作组合的几个网站:
- http://alexgaribay.com/2014/06/16/authentication-in-play-framework-using-java/
- https://www.playframework.com/documentation/2.2.1/JavaGuide4
问题
有没有办法全局验证用户是否应该有权访问页面以及如何获取 session 变量?
*请注意,我对使用第三方插件进行身份验证不感兴趣。
即使我会重新考虑使用动作合成,你也可以修正选项 1。
创建自定义注释来标记不需要验证的操作。
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface NoAuthRequired {}
然后更改您的 HttpRequestHandler 实现。
public class RequestHandler extends DefaultHttpRequestHandler {
@Override
public Action createAction(Http.Request request, Method actionMethod) {
return new Action.Simple() {
@Override
public F.Promise<Result> call(Http.Context ctx) throws Throwable {
// if the action is annotated with @NoAuthRequired or user is logged in delegate to it
if (actionMethod.isAnnotationPresent(NoAuthRequired.class) || ctx.session().containsKey("loggedIn")) {
return delegate.call(ctx);
}
// otherwise, block access
else {
return F.Promise.pure(forbidden("You're not allowed"));
}
}
};
}
}
这样,除非明确注释,否则每条路线都需要验证。
从代码中可以看出,会话是通过上下文访问的。