当用户尝试访问管理 Controller 中的页面(主要是 CRUD 内容)时,他将被重定向到登录页面。而且,如果凭据正确并且他确实是管理员,他将开始被重定向到他在上一个请求中想要访问的页面。
每当有人试图访问禁止访问的页面时,他就会被重定向到以下 Controller :
public static void login(String returnUrl) throws Throwable {
Http.Cookie remember = request.cookies.get("rememberme");
flash.put("url",returnUrl);
if (remember != null && remember.value.indexOf("-") > 0) {
String sign = remember.value.substring(0, remember.value.indexOf("-"));
String username = remember.value.substring(remember.value.indexOf("-") + 1);
if (Crypto.sign(username).equals(sign)) {
session.put("username", username);
redirectToOriginalURL(returnUrl);
}
}
flash.keep();
render();
}
执行 authenticte(...) 方法:
public static void authenticate(@Required String username, String password, boolean remember, String returnUrl) throws Throwable {
// Check tokens
Boolean allowed = false;
// This is the official method name
allowed = (Boolean) Security.invoke("authenticate", username, password);
if (validation.hasErrors() || !allowed) {
flash.keep("url");
flash.error("secure.error");
params.flash();
login(returnUrl);
}
// Mark user as connected
session.put("username", username);
// Remember if needed
if (remember) {
response.setCookie("rememberme", Crypto.sign(username) + "-" + username, "30d");
}
// Redirect to the original URL (or /)
flash.keep("url");
redirectToOriginalURL(returnUrl);
}
注意参数列表中的String returnUrl
。此 Controller 始终在 View 中使用 response.url
值调用。
redirectToOriginalURL() 是一种在参数或 flash 范围内接收 returnUrl 的方法。
static void redirectToOriginalURL(String returnUrl) throws Throwable {
if(returnUrl==null) returnUrl = flash.get("url");
if (returnUrl == null) {
returnUrl = "/";
}
redirect(returnUrl);
}
这在 Firefox 和 Internet Explorer 中运行良好。但是当我尝试在 Google Chrome 中执行此操作时,returnUrl 为 null
。这是一个已知问题,还是我做错了什么?
没有特殊要求或任何东西。从无法访问的页面 (localhost:9000/admin
) 重定向时,url 是 http://localhost:9000/account?returnUrl=%2Fadmin
。所以没有错...
因此,错误必须出在身份验证 Controller 中,它似乎无法将参数传递给 redirectToOriginalURL 方法。但是,话又说回来,仅限于 Google Chrome。
建议?
最佳答案
我是这样工作的:
确保 checkAccess 方法使用当前 url 调用登录方法:
static void checkAccess() throws Throwable {
// Authent
if (!session.contains("username")) {
login(request.method.equals("GET") ? request.url : "/");
}
}
然后在 login.html View 中添加隐藏字段,这是您已经传递给登录方法的参数:
#{form @authenticate()}
<input type="hidden" name="returnUrl" value="${params.returnUrl}">
...
#{/form}
或者直接在form.action中添加returnUrl参数:
#{form @authenticate().add("returnUrl", params.returnUrl)}
就是这样。而且您不需要闪光灯。
关于java - Flash 作用域中的变量在 Google Chrome 中不存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5635127/