基于SpringMVC的登录拦截器
2016-03-09 21:48
666 查看
基于SpringMVC的登录拦截器
1.Struts2的核心过滤器配置
2.springmvc-servlet.xml配置
3. 登陆拦截器 UserSecurityInterceptor
4. 权限拦截器:AuthoritySecurityInterceptor
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方法执行完毕之后,执行(没有抛异常的 话)----------"); } }
相关文章推荐
- java 线程4
- Java开发环境配置
- 我爱学Java之对象序列化
- elasticsearch结合spring springmvc jest 使用做成web架构
- Java 折半查找
- java线程3
- eclipse打包jar时包含第三方jar包的相关问题
- Java初级工程师应该具备的知识点
- 【转】人生如梦游戏间,RPG游戏开源开发讲座(JAVA篇)[5]——一树双花
- java 设计模式
- Java 进阶 之 抽象类与接口 比较(二)
- 【转】人生如梦游戏间,RPG游戏开源开发讲座(JAVA篇)[4]——一步莲华
- leetcode:Add Two Numbers 【Java】
- 礼拜三log~java web框架探索&baidu地图
- 2016年3月8_spring
- java 线程2
- Java之泛型进阶——泛型代码转化为普通代码
- java线程一
- Eclipse中自动import包
- Java反射的学习