但当我们用配置/xxx.html=authc这种方式,限制用户访问/xxx.html连接时必须是认证过的用户,否则shiro的filter将会重定向到登录页面,上面的方法应当好处理了。不过shiro在跳转前有记录跳转前的页面。前没有认证的用户请求需要认证的链接时,shiro在跳转前会把跳转过来的页面链接保存到session的attribute中,key的值叫shiroSavedRequest,我们可以能过WebUtils类拿到。
当用户登录成功后,可能通过String url = WebUtils.getSavedRequest(request).getRequestUrl();,拿到跳转到登录页面前的url,然后redirect到这个url。其实我们可以看看这个方法的源码:
public static SavedRequest getSavedRequest(ServletRequest request) {
SavedRequest savedRequest = null;
Subject subject = SecurityUtils.getSubject();
Session session = subject.getSession(false);
if (session != null) {
savedRequest = (SavedRequest) session.getAttribute(SAVED_REQUEST_KEY);
}
return savedRequest;
}
从session中拿到SaveRequest。不过值得注意的是,这个SaveRequest是在用户通过上面方式跳转登录时shiro才会保存,并且不会改变,除非下一次跳转再次发生。并不是每一个请求,shiro都会把上一个请求保存到session中。所以,不能通过WebUtils.getSavedRequest(request)在任何地方调用来拿到上一个页面的请求。这个方法的调用,更应该是在用户登录成功后,重定向到页面时使用。
重写FormAuthenticationFilter类 我是这么做的。
Subject subject, ServletRequest request, ServletResponse response)
throws Exception {
WebUtils.issueRedirect(request, response, getSuccessUrl());
return false;
}
登录超时提醒
这里不是使用监听 思路都一样,简单说下:
如果你使用的是FormAuthenticationFilter,那么继承FormAuthenticationFilter覆盖onAccessDenied方法,方法实现:
- if (isLoginRequest(request, response)) {
- if (isLoginSubmission(request, response)) {
- return executeLogin(request, response);
- } else {
- return true;
- }
- } else {
- if(AjaxUtils.isAjaxRequest(WebUtils.toHttp(request))){
- HttpServletResponse res = WebUtils.toHttp(response);
- res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
- }else{
- redirectToLogin(request, response);
- }
- / saveRequestAndRedirectToLogin(request, response);
- return false;
- }
然后前台设置ajax全局状态码处理 捕获401,给出提示或做进一步处理