今天做项目的时候,发现使用shiro时候,session失效后shiro配的successUrl不生效的问题。
/img/** = anon
经过上网查询:
原因一:http://www.cnblogs.com/yeming/p/5480639.html
原因二:http://www.bubuko.com/infodetail-1421844.html (有源码解释)
粘贴原因一内容:
用上面的配置会有这样的情况:
1.如果是访问其他已存在的页面被拦截到登录页面,登录后就会跳转到之前的页面。
2.如果是直接访问登录页面或者是通过退出登录到登录页面,再次登录就会跳转到“/”。
3.不管怎么样,都没有跳转到successUrl指定的url。
原因是这样的:
successUrl配置只是做为一种附加配置,只有session中没有用户请求地址时才会使用successUrl。系统默认的是认证成功后跳转到上一次请求的路径,如果是首次请求,那shiro就会跳转到默认虚拟路径“/”,也就是跳转到index.jsp。
解决方法:
简单一点的话就可以直接在index.jsp里面把请求重定向到你指定的页面
粘贴原因二内容:
做项目的时候,特别是当访问的url是iframe的页面的时候,session又过期了,跳转到登陆页,完成登陆操作后,返回了只有iframe的页面,相当不好看。虽然在shiro里设
置了successUrl,但是没有起作用。
debug后跟进去观察后发现FormAuthenticationFilter成功登陆后,会调用它的onLoginSuccess方法,最后会调用下面这个实际执行的方法。
WebUtils.redirectToSavedRequest(request, response, getSuccessUrl());
这个方法实际做什么了。
public static void redirectToSavedRequest(ServletRequest request, ServletResponse response,
String fallbackUrl)throws IOException {
String successUrl = null;
boolean contextRelative = true;
SavedRequest savedRequest = WebUtils.getAndClearSavedRequest(request);
if (savedRequest != null &&
savedRequest.getMethod().equalsIgnoreCase(AccessControlFilter.GET_METHOD)){
successUrl = savedRequest.getRequestUrl();
contextRelative = false;
}
if (successUrl == null) {
successUrl = fallbackUrl;
}
if (successUrl == null) {
throw new IllegalStateException(".....");
}
WebUtils.issueRedirect(request, response, successUrl, null, contextRelative);
}
可以看出如果由之前的页面跳转到登陆页的话,savedRequest保存了原来的地址,这个地址会取代我们设置的successUrl;只有当savedRequest为null的时候,
successUrl才会是我们设置的地址。
好了,那我们要怎么做避免它返回页面,只返回到我们指定的页面呢?如果要我选的话,我会选择继承FormAuthenticationFilter并重写父类的方法AuthenticationFilter的
issueSuccessRedirect方法,最后差不多就是
package util.shrio;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
/**
* @Description MyFormAuthenticationFilter 自定义session失效跳转页面
* @Date 2017年9月18日 下午4:48:03
*/
public class MyFormAuthenticationFilter extends FormAuthenticationFilter {
// 制定session跳转url
private final String successUrl = "/main/index.do";
@Override
protected void issueSuccessRedirect(ServletRequest request, ServletResponse response) throws Exception {
WebUtils.issueRedirect(request, response, successUrl, null, true);
}
}
在原来的配置上增加:
/img/** = anon