- 用户在未登录时访问网站中某个需要登录后才能访问的URL
- 请求被拦截跳转登陆页面
- 登陆后跳转未登录时访问的路径
具体实现:
1.拦截器 配置文件shiro.ini
[urls] /usr/info/** = authc2 [filters] authc2=com.fiter.FormAuthenticationFilter2
解释:
(1)filters指代自定义拦截器
authc2=com.fiter.FormAuthenticationFilter2,其中等号右侧为自定义拦截器代码,左侧为
指代
(2)urls指代需要进行拦截的URI
若该访问路径的URI需要有某种限制即需要被拦截器过滤下,即配制该拦截器
2.自定义拦截器
public class FormAuthenticationFilter2 extends FormAuthenticationFilter { private static final Logger log = LoggerFactory.getLogger(FormAuthenticationFilter2.class);//定义日志输出 @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { if (isLoginRequest(request, response)) { if (isLoginSubmission(request, response)) { } return executeLogin(request, response); } else { if (log.isTraceEnabled()) { log.trace("Login page view."); } //allow them to see the login page ;) return true; } } else { if (log.isTraceEnabled()) { log.trace("Attempting to access a path which requires authentication. Forwarding to the " + "Authentication url [" + getLoginUrl() + "]"); } HttpServletRequest httpRequest = WebUtils.toHttp(request); // 组装URL StringBuilder returnUrl = new StringBuilder("http://t.com"); returnUrl.append(httpRequest.getRequestURI()); Enumeration enumeration = httpRequest.getParameterNames(); if(enumeration != null) { boolean first = true; while(enumeration.hasMoreElements()) { Object param = enumeration.nextElement(); if(param != null && httpRequest.getParameter(param.toString()) != null) { if(first) { returnUrl.append("?"); } returnUrl.append(param).append("=").append(httpRequest.getParameter(param.toString())).append("&"); first = false; } } } String encodedReturnUrl = returnUrl.toString(); if(encodedReturnUrl.endsWith("&")) { encodedReturnUrl = encodedReturnUrl.substring(0, encodedReturnUrl.length() - 1); } encodedReturnUrl = URLEncoder.encode(encodedReturnUrl, "UTF-8"); StringBuilder builder = new StringBuilder("/login/loginpage.do?returnUrl="); builder.append(encodedReturnUrl); setLoginUrl(builder.toString()); redirectToLogin(request, response); return false; } } }
解释:
(1)request.getHeader("Referer"))获取上次访问的URL链接
a.原理:referer是浏览器在用户提交请求当前页面中的一个链接时,将当前页面的URL放在头
域中提交给服务端的,如当前页面为a.html,它里面有一个b.html的链接,当用户要访问b.html
时浏览器就会把a.html作为referer发给服务端.
b.限制:request.getHeader("Referer")要走HTTP协议才有值,也就是说要通过<a
href="url" />标记,才能获取到值。当然通过表单提交的也可以。而通过location或是<a
href="javascript:window.location=''" />是得不到值的
c.由于此处访问时未通过HTTP协议,故通过该方式获取的结果为空
(2)拦截器组装拦截后跳转的URL
3.实现效果
匿名访问: http://localhost:8080/m2b/usr/info/getuserinfo.do
拦截跳转: http://localhost:8080/m2b/login/loginpage.do?returnUrls=http%3A%2F%2Ft.com%2Fm2b%2Fusr%2Finfo%2Fgetuserinfo.do
该跳转URL为拦截器指定
4.跳转登陆
@Action(value = "loginpage", results = { @Result(name = ResultTypeConstants.REDIRECT, type = ResultTypeConstants.REDIRECT, location = "/login/index.do"), @Result(name = ResultTypeConstants.ISSUE_REDIRECT, type = ResultTypeConstants.REDIRECT, location = "/login/issueredirect.do"), @Result(name = SUCCESS, type = ResultTypeConstants.VELOCITY, location = "/login.vm") }) @SkipValidation public String loginpage() { returnurl = request.getParameter("returnUrl"); if(returnurl == null) { returnurl = request.getHeader("Referer"); } logger.info("returnUrl:" + returnurl); request.getSession().setAttribute("returnUrl", returnurl); // 用户已登录 Subject currentUser = SecurityUtils.getSubject(); if (currentUser != null && currentUser.isAuthenticated()) { return ResultTypeConstants.REDIRECT; } if (currentUser != null && currentUser.isRemembered()) { user = (User) currentUser.getPrincipal(); rememberme = "1"; } return SUCCESS; }
解释:
(1)request.getParameter("returnUrl");获取拦截器组装的指定的URL中的参数,即http://t.com?returnUrl=http%3A%2F%2F%2Fm2b%2Fusr%2Finfo%2Fgetuserinfo.do
(2)request.getParameter("");的使用
a.获取URL中的参数
b.获取页面通过submit方式的传值
<form. name="form1" method="post" action="authenticate.jsp"> 请输入用户姓名:<input type="text" name="username"> <input type="submit" name="Submit" value="提交"> </form>