您的位置:首页 > 编程语言 > Java开发

基于SpringMVC的登录拦截器

2017-04-01 20:52 429 查看
1.Struts2的核心过滤器配置

[html] view
plain copy

print?





<!-- 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配置

[html] view
plain copy

print?





<?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

[java] view
plain copy

print?





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

[java] view
plain copy

print?





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方法执行完毕之后,执行(没有抛异常的

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

}

}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: