基于SHIRO实现用户登陆后跳转其匿名访问的URL路径

需求描述:

  • 用户在未登录时访问网站中某个需要登录后才能访问的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>

猜你喜欢

转载自mingyundezuoan.iteye.com/blog/2227532