基于SpringMVC的登录拦截器

                                                 基于SpringMVC的登录拦截器


  1.Struts2的核心过滤器配置

 <!-- Struts2的核心过滤器配置 -->
    <filter>
        <filter-name>struts2</filter-name>
        <filter-

class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter

-class>
    </filter>
    <!-- Struts2过滤器拦截所有的.action请求 -->
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>*.action</url-pattern>
    </filter-mapping>
    

    2.springmvc-servlet.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

xmlns:p="http://www.springframework.org/schema/p"
	xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context 
            http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/aop 
            http://www.springframework.org/schema/aop/spring-aop.xsd
            http://www.springframework.org/schema/tx 
            http://www.springframework.org/schema/tx/spring-tx.xsd
            http://www.springframework.org/schema/mvc 
            http://www.springframework.org/schema/mvc/spring-mvc.xsd">

	<!-- 启用spring mvc 注解(默认的注解映射的支持) -->
	<mvc:annotation-driven />
        
	<!-- 设置使用注解的类所在的jar包(自动扫描的包名) -->
	<context:component-scan
		base-package="com.ouc.ulab.controller" />

	<!--进行静态资源的访问 -->
	<mvc:resources mapping="/static/**" location="/static/" />

	<!-- 配置资源文件,防止被拦截 -->
	<!-- <mvc:resources location="/WEB-INF/view/image/" mapping="/image/**"/> 
		<mvc:resources location="/WEB-INF/view/js/" mapping="/js/**"/> 

<mvc:resources 
		location="/WEB-INF/view/css/" mapping="/css/**"/> -->

	<!-- 拦截器 -->
	<mvc:interceptors>
	   <bean 

class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
			<property name="paramName" value="lang" ></property>
	   </bean>
	</mvc:interceptors> 
	
	<mvc:interceptors>
	    <mvc:interceptor>
			<mvc:mapping path="/*.do" />
			<mvc:mapping path="/*.ajax" />
			<mvc:mapping path="/*.jsp" />
			<mvc:mapping path="/*.html" />

			<!-- 二级目录 -->
			<mvc:mapping path="/*/*.do" />
			<mvc:mapping path="/*/*.ajax" />
			<mvc:mapping path="/*/*.jsp" />
			<mvc:mapping path="/*/*.html" />

			<!-- 需排除拦截的地址 -->
			<mvc:exclude-mapping path="/login.jsp" />
			<mvc:exclude-mapping path="/login.do" />
            <mvc:exclude-mapping path="/getUserLoginInfo.do" />
           
			<bean 

class="com.ouc.ulab.interceptor.UserSecurityInterceptor"></bean>
		</mvc:interceptor>
	</mvc:interceptors>

    <mvc:interceptors>
      <mvc:interceptor>
		   <mvc:mapping path="/*.do" />
			<mvc:mapping path="/*.ajax" />
			<mvc:mapping path="/*.jsp" />
			<mvc:mapping path="/*.html" />

			<mvc:mapping path="/*/*.do" />
			<mvc:mapping path="/*/*.ajax" />
			<mvc:mapping path="/*/*.jsp" />
			<mvc:mapping path="/*/*.html" /> 
			
			<mvc:exclude-mapping path="/login.jsp" />
			<mvc:exclude-mapping path="/login.do" />
			<mvc:exclude-mapping path="/loadHome.do" />
                        <mvc:exclude-mapping path="/getUserLoginInfo.do" />
            
			<bean 

class="com.ouc.ulab.interceptor.AuthoritySecurityInterceptor" > 
			</bean>
		</mvc:interceptor>
    </mvc:interceptors> 
    
    <!-- 对转向页面的路径解析。prefix:前缀, suffix:后缀 对模型视图名称的解析,即

在模型视图名称添加前后缀 InternalResourceViewResolver默认的就是JstlView所以这里就不

用配置viewClass了 -->
	<bean 

class="org.springframework.web.servlet.view.InternalResourceViewResolver"
		p:prefix="/" p:suffix=".jsp">
	</bean>

	<!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射, 配置一个基于注解

的定制的WebBindingInitializer,解决日期转换问题,方法级别的处理器映射 -->
	<bean 

class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapte

r">
		<!-- 配置一下对json数据的转换 -->
		<property name="messageConverters">
			<list>
				<bean 

class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">

</bean>
			</list>
		</property>
	</bean>
</beans>


    3. 登陆拦截器 UserSecurityInterceptor

package com.ouc.ulab.interceptor;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import java.net.URLEncoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.method.HandlerMethod;

import com.haier.openplatform.security.LoginContext;
import com.haier.openplatform.security.LoginContextHolder;
import com.haier.openplatform.security.SessionSecurityConstants;

import com.ouc.ulab.security.BaseUser;

public class UserSecurityInterceptor implements HandlerInterceptor{

    //private List<String> excludedUrls;
    
    private static final String DEFAULT_LOGIN = "/login.jsp";  
    
    //public final static String SESSIONNAME = "sessionName";
    
    private List<String> noLoginAuthUrlList = new ArrayList<String>();
	/**
	 * 用户session中的用户表示
	 */
	private String keyUserName = SessionSecurityConstants.KEY_USER_NAME;
	private String keyUserNickName = 

SessionSecurityConstants.KEY_USER_NICK_NAME;
	private String keyUserId = SessionSecurityConstants.KEY_USER_ID;
	private String keyLocalLanguage = 

SessionSecurityConstants.KEY_LOCAL_LANGUAGE;

	public void setKeyUserName(String keyUserName) {
		this.keyUserName = keyUserName;
	}

	public void setKeyUserId(String keyUserId) {
		this.keyUserId = keyUserId;
	}

	public void setKeyLocalLanguage(String keyLocalLanguage) {
		this.keyLocalLanguage = keyLocalLanguage;
	}

	public void setNoLoginAuthUrlList(List<String> noLoginAuthUrlList) {
		this.noLoginAuthUrlList = noLoginAuthUrlList;
	}
	
    /*public List<String> getExcludedUrls() {
	   return excludedUrls;
	}

	public void setExcludedUrls(List<String> excludedUrls) {
	    this.excludedUrls = excludedUrls;
	}*/

    /** 
     * preHandle方法是进行处理器拦截用的,顾名思义,该方法将在Controller处理之前进

行调用,SpringMVC中的Interceptor拦截器是链式的,可以同时存在 
     * 多个Interceptor,然后SpringMVC会根据声明的前后顺序一个接一个的执行,而且所有

的Interceptor中的preHandle方法都会在 
     * Controller方法调用之前调用。SpringMVC的这种Interceptor链式结构也是可以进行中

断的,这种中断方式是令preHandle的返 
     * 回值为false,当preHandle的返回值为false的时候整个请求就结束了。 
     */  
	@SuppressWarnings("deprecation")
	@Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse res,
            Object obj) throws Exception {
		System.out.println("-------在Action之前执行,如果返回true,则继续向后

执行--------");
		
		/*//请求的路径
        String contextPath = req.getContextPath();
        String url= req.getServletPath().toString();
    	System.out.println(contextPath);
    	HttpSession session = req.getSession();
    	
    	BaseUser user = new BaseUser();
		user.setUserId((Long)session.getAttribute(keyUserId));
		user.setUserName((String)session.getAttribute(keyUserName));
		user.setNickName((String)session.getAttribute(keyUserNickName));
    	
        System.out.println("用户名:"+user.getUserName());
        
		if(!isLogin(req)){
			res.sendRedirect(contextPath + "/login.jsp?redirectURL="
                    + URLEncoder.encode(url));
			return false;
		}
		
		return true;*/
    	
            
    	//请求的路径
        String contextPath = req.getContextPath();
        String  url= req.getServletPath().toString();
    	System.out.println(contextPath);
    	HttpSession session = req.getSession();
    	String userName = (String) session.getAttribute(keyUserName);
        System.out.println("用户名:"+userName);
        //这里可以根据session的用户来判断角色的权限,根据权限来重定向不同的页面,简

单起见,这里只是做了一个重定向
        if (StringUtils.isEmpty(userName)) {
            //被拦截,重定向到login界面
        	res.sendRedirect(contextPath + DEFAULT_LOGIN + "?redirectURL="
                    + URLEncoder.encode(url));
            return false;
        }
        return true;
        
    }
	
	/** 
     * 该方法也是需要当前对应的Interceptor的preHandle方法的返回值为true时才会执行。

该方法将在整个请求完成之后,也就是DispatcherServlet渲染了视图执行, 
     * 这个方法的主要作用是用于清理资源的,当然这个方法也只能在当前这个Interceptor

的preHandle方法的返回值为true时才会执行。 
     */ 
    
    @Override
    public void afterCompletion(HttpServletRequest arg0,
            HttpServletResponse arg1, Object arg2, Exception ex)
            throws Exception {
        // TODO Auto-generated method stub
    	System.out.println("----在Action 方法执行完毕之后,无论是否抛出异常,通常用来

进行异常处理----------");
    }
    
    /** 
     * 这个方法只会在当前这个Interceptor的preHandle方法返回值为true的时候才会执行。

postHandle是进行处理器拦截用的,它的执行时间是在处理器进行处理之 
     * 后,也就是在Controller的方法调用之后执行,但是它会在DispatcherServlet进行视

图的渲染之前执行,也就是说在这个方法中你可以对ModelAndView进行操 
     * 作。这个方法的链式结构跟正常访问的方向是相反的,也就是说先声明的Interceptor

拦截器该方法反而会后调用,这跟Struts2里面的拦截器的执行过程有点像, 
     * 只是Struts2里面的intercept方法中要手动的调用ActionInvocation的invoke方法,

Struts2中调用ActionInvocation的invoke方法就是调用下一个Interceptor 
     * 或者是调用action,然后要在Interceptor之前调用的内容都写在调用invoke之前,要

在Interceptor之后调用的内容都写在调用invoke方法之后。 
     */  
    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
            Object arg2, ModelAndView arg3) throws Exception {
        // TODO Auto-generated method stub
    	 System.out.println("----在Action方法执行完毕之后,执行(没有抛异常的

话)----------");
    }
    
	protected boolean isLogin(HttpServletRequest httpServletRequest) {
		String currentUrl = httpServletRequest.getRequestURI();
		
		noLoginAuthUrlList.add("/login.jsp");
		
		for(String url : noLoginAuthUrlList){
			if(currentUrl.startsWith(url)){
				return true;
			}
		}
		
		HttpSession httpSession = httpServletRequest.getSession();
		String userName = (String) httpSession.getAttribute(keyUserName);
		if (userName == null) {
			// 仅仅记住get请求的链接
			if (StringUtils.equalsIgnoreCase

(httpServletRequest.getMethod(),
					"GET")) {
				HttpSession session = 

httpServletRequest.getSession();
				String servletPath = 

httpServletRequest.getServletPath();
				String fullURL = new StringBuffer

(servletPath).append(
						toParameterString

(httpServletRequest)).toString();
				session.setAttribute(
						

SessionSecurityConstants.KEY_LAST_VISIT_URL, fullURL);
			}
			return false;
		}
		return true;
	}
	
	/**
	 * 
	 * @param httpServletRequest
	 * @return
	 */
	private String toParameterString(HttpServletRequest httpServletRequest) {
		Enumeration<String> paramEnumeration = 

httpServletRequest.getParameterNames();
		if (!paramEnumeration.hasMoreElements()) {
			return "";
		}
		StringBuffer stringBuffer = new StringBuffer();
		while (paramEnumeration.hasMoreElements()) {
			String paramName = paramEnumeration.nextElement();
			stringBuffer.append("&");
			stringBuffer.append(paramName);
			stringBuffer.append("=");
			stringBuffer.append(httpServletRequest.getParameter

(paramName));
		}
		stringBuffer.replace(0, 1, "?");
		return stringBuffer.toString();
	}
}

    4. 权限拦截器:AuthoritySecurityInterceptor

package com.ouc.ulab.interceptor;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.haier.openplatform.hac.dto.HacResourceDTO;
import com.haier.openplatform.hac.resource.dto.enu.ResourceTypeEnum;
import com.haier.openplatform.hac.resource.service.HacResourceServiceClient;
import com.haier.openplatform.security.AbstractAuthenticator;
import com.haier.openplatform.security.Authentication;
import com.haier.openplatform.security.DefaultUrlAuthenticator;
import com.haier.openplatform.security.SessionSecurityConstants;
import com.ouc.ulab.interceptor.AuthResources;

public class AuthoritySecurityInterceptor implements HandlerInterceptor {
	
	@Autowired
	private static HacResourceServiceClient resourceServiceClient; 
	
	/**
	 * 无权限跳转的页面
	 */
	private static final String NOAUTHPAGE = "/NoAuth.jsp";

	//当前用户所拥有的资源
	private List<HacResourceDTO> resources;
	
	//判断资源是否已获取的布尔变量
	private boolean HACRES_ISGET = false;
	
	/** 
     * preHandle方法是进行处理器拦截用的,顾名思义,该方法将在Controller处理之前进

行调用,SpringMVC中的Interceptor拦截器是链式的,可以同时存在 
     * 多个Interceptor,然后SpringMVC会根据声明的前后顺序一个接一个的执行,而且所有

的Interceptor中的preHandle方法都会在 
     * Controller方法调用之前调用。SpringMVC的这种Interceptor链式结构也是可以进行中

断的,这种中断方式是令preHandle的返 
     * 回值为false,当preHandle的返回值为false的时候整个请求就结束了。 
     */ 
	
	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws 

Exception {
		HttpSession httpSession = request.getSession();
		
		// 根据应用编码、用户名、当前语言和版本获取该用户所拥有的权限列表
          (此处调用外部dubbo接口获取当前登录用户的资源列表)
		
		if (!HACRES_ISGET){
			ClassPathXmlApplicationContext cxt = new 

ClassPathXmlApplicationContext(
					new String[]{"classpath:dubbo-

consumer.xml","classpath:springmvc-servlet.xml"},true);
			
			cxt.start();
			
			resourceServiceClient = (HacResourceServiceClient)

cxt.getBean("resourceServiceClient");
			
			resources = resourceServiceClient.getResourcesByAppAndUser

("H001", "wangxi", "zh_CN", "1.0");
			
			HACRES_ISGET = true;
		}
		
		System.out.println("王玺所拥有的权限列表:" + resources.size());
		for(int i=0;i<resources.size();i++)
		{
			System.out.println("资源序号: " + (i+1));
			System.out.println("AppName: " + resources.get

(i).getAppName());
			System.out.println("AppCode: " + resources.get

(i).getAppCode());
			System.out.println("BaseUrl: " + resources.get

(i).getBaseUrl());
			System.out.println("UserId: " + resources.get(i).getUserId

());
			System.out.println("AppId: " + resources.get(i).getAppId

());
			System.out.println("CreateBy: " + resources.get

(i).getCreateBy());
			System.out.println("Code: " + resources.get(i).getCode());
			System.out.println("Configuration: " + resources.get

(i).getConfiguration());
			System.out.println("Name: " + resources.get(i).getName());
			System.out.println("ModuleId: " + resources.get

(i).getModuleId());
			System.out.println("Url: " + resources.get(i).getUrl());
			System.out.println("FileId: " + resources.get(i).getFileId

());
			System.out.println("Status: " + resources.get(i).getStatus

());
			System.out.println();
		}
    	
		// KEY_AUTHENTICATION  用户授权信息
		String authentication = (String)httpSession.getAttribute

(SessionSecurityConstants.KEY_AUTHENTICATION);
		
		AuthResources auth = new AuthResources();
		
		for(HacResourceDTO resource : resources){
			ResourceTypeEnum resourceType = ResourceTypeEnum.toEnum

(resource.getType());
			if(resourceType == ResourceTypeEnum.URL_RESOURCE || 

resourceType == ResourceTypeEnum.TODO_RESOURCE){
				auth.getUrlResources().add(resource.getUrl());
				if(StringUtils.isNotEmpty(resource.getCode())){
					auth.getComponentResources().add

(resource.getCode());
				}
			}else if(resourceType == 

ResourceTypeEnum.COMPONENT_RESOURCE){
				auth.getComponentResources().add(resource.getCode

());
			}
		}
		
		if (authentication == null || auth.getUrlResources().isEmpty()) {
			// Session存放的用戶登录名   KEY_USER_NAME
			String userCode = (String)httpSession.getAttribute

(SessionSecurityConstants.KEY_USER_NAME);
			//authentication = getAuthentication(userCode, request);
			//httpSession.setAttribute

(SessionSecurityConstants.KEY_AUTHENTICATION, authentication);
		}
		
		String contextPath = request.getContextPath();
		String currentUrl = request.getServletPath();
		System.out.println("目前的URL:"+currentUrl);
		
		if(auth.getUrlResources().size()>0){
			for(int j=0; j<auth.getUrlResources().size();j++){
				System.out.println(auth.getUrlResources().get(j));
				if(auth.getUrlResources().get(j).equals

(currentUrl)){
					return true;
				}
			}
		}
			
		/*if(!authenticator.hasUrlAuth(currentUrl)){
			response.sendRedirect(NOAUTHPAGE);
			return false;
		}*/
		
		response.sendRedirect(contextPath + NOAUTHPAGE);

		return false;
	}
	
	/** 
     * 该方法也是需要当前对应的Interceptor的preHandle方法的返回值为true时才会执行。

该方法将在整个请求完成之后,也就是DispatcherServlet渲染了视图执行, 
     * 这个方法的主要作用是用于清理资源的,当然这个方法也只能在当前这个Interceptor

的preHandle方法的返回值为true时才会执行。 
     */ 
    
    @Override
    public void afterCompletion(HttpServletRequest arg0,
            HttpServletResponse arg1, Object arg2, Exception ex)
            throws Exception {
        // TODO Auto-generated method stub
    	System.out.println("----在Action 方法执行完毕之后,无论是否抛出异常,通常用来

进行异常处理----------");
    }
    
    /** 
     * 这个方法只会在当前这个Interceptor的preHandle方法返回值为true的时候才会执行。

postHandle是进行处理器拦截用的,它的执行时间是在处理器进行处理之 
     * 后,也就是在Controller的方法调用之后执行,但是它会在DispatcherServlet进行视

图的渲染之前执行,也就是说在这个方法中你可以对ModelAndView进行操 
     * 作。这个方法的链式结构跟正常访问的方向是相反的,也就是说先声明的Interceptor

拦截器该方法反而会后调用,这跟Struts2里面的拦截器的执行过程有点像, 
     * 只是Struts2里面的intercept方法中要手动的调用ActionInvocation的invoke方法,

Struts2中调用ActionInvocation的invoke方法就是调用下一个Interceptor 
     * 或者是调用action,然后要在Interceptor之前调用的内容都写在调用invoke之前,要

在Interceptor之后调用的内容都写在调用invoke方法之后。 
     */  
    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
            Object arg2, ModelAndView arg3) throws Exception {
        // TODO Auto-generated method stub
    	 System.out.println("----在Action方法执行完毕之后,执行(没有抛异常的

话)----------");
    }
	
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值