基于SpringMVC的登录拦截器

来源:互联网 发布:mac有线网络设置 编辑:程序博客网 时间:2024/06/01 07:18

                                                 基于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-scanbase-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.AnnotationMethodHandlerAdapter"><!-- 配置一下对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 {@Autowiredprivate 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的时候整个请求就结束了。      */ @Overridepublic 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_NAMEString 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 0
原创粉丝点击