SpringMVC HandlerInterceptorAdapter登陆验证拦截器
来源:互联网 发布:移动协同软件下载 编辑:程序博客网 时间:2024/04/30 02:32
工作中用到了验证用户是否登陆,判断是否有session值,想到了用SpringMVC HandlerInterceptorAdapter拦截器,方便,实用性大。
Spring MVC的拦截器不仅可实现Filter的所有功能,还可以更精确的控制拦截精度。
Spring为我们提供了org.springframework.web.servlet.handler.HandlerInterceptorAdapter这个适配器,继承此类,可以非常方便的实现自己的拦截器。它有三个方法:
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; } public void postHandle( HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } public void afterCompletion( HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { }
分别实现预处理、后处理(调用了Service并返回ModelAndView,但未进行页面渲染)、返回处理(已经渲染了页面)
在preHandle中,可以进行编码、安全控制等处理;
在postHandle中,有机会修改ModelAndView;
在afterCompletion中,可以根据ex是否为null判断是否发生了异常,进行日志记录。
如果基于xml配置使用Spring MVC,
可以利用SimpleUrlHandlerMapping、BeanNameUrlHandlerMapping进行Url映射(相当于struts的path映射)和拦截请求(注入interceptors),
如果基于注解使用Spring MVC,可以使用DefaultAnnotationHandlerMapping注入interceptors。
注意无论基于xml还是基于注解,HandlerMapping bean都是需要在xml中配置的。
我做的功能是用户登录验证,代码如下:
@Controllerpublic class SessionInjectionInterceptor extends HandlerInterceptorAdapter { private static Logger log = Logger .getLogger(SessionInjectionInterceptor.class); @Autowired private HttpSession session; @Autowired private ILoginService loginService; public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 获取当前登录人信息 Authentication authentication = SecurityContextHolder.getContext() .getAuthentication(); // 判断当前用户session为null,并且已经做了登陆验证。 if (authentication != null && session .getAttribute(Constants.Session.ACCOUNT_ATTRIBUTE_NAME) == null) { String username = authentication.getName(); if (!"anonymousUser".equals(username)) { // account Account account = (Account) loginService .getAccountByName(username); session.setAttribute(Constants.Session.ACCOUNT_ATTRIBUTE_NAME, account); } else { // 做无浏览权限验证,或者未登陆用户,转发到登陆页面 session.setAttribute(Constants.Session.ACCOUNT_ATTRIBUTE_NAME, null); request.getRequestDispatcher("/login.jsp").forward( request, response); return false; } } return super.preHandle(request, response, handler); }}
用户登录验证,和前台页面配合:
public class CustomAuthenticationProvider implements AuthenticationProvider { private static Logger log = Logger .getLogger(CustomAuthenticationProvider.class); private JdbcTemplate jdbcTemplate; public void setDataSource(DataSource dataSource) { this.jdbcTemplate = new JdbcTemplate(dataSource); } @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { // 获取前台传送的用户名和密码 String username = authentication.getName(); String password = authentication.getCredentials().toString(); log.debug("username = " + username + " password = " + password); // 根据用户名密码查询用户是否存在,并返回编码值 UserResult ur = authorize(username, password); log.debug(ur.toJson()); // 判断编码值是否是success, if (ur.getCode().equals(UserResult.Code.SUCCESS)) { List<GrantedAuthority> grantedAuths = new ArrayList<GrantedAuthority>(); grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER")); return new UsernamePasswordAuthenticationToken(username, password, grantedAuths); } else { throw new AuthenticationException(ur.getMsg().getContent()) { private static final long serialVersionUID = -5506038021601762240L; }; } } @Override public boolean supports(Class<?> authentication) { return authentication.equals(UsernamePasswordAuthenticationToken.class); } private UserResult authorize(final String name, final String password) { log.info("authorize begin. name = " + name); if (name == "" || null == name) { return new UserResult(Code.FAIL, Msg.ILLEGAL_USERNAME); } // TODO 根据名称查询用户是否存在,暂用自己测试 String sql = "select * from ACCOUNT where LLOGIN_ID = ? and PPASSWORD = ?"; Object[] params = { name,password }; Account account = null; try { account = jdbcTemplate.queryForObject(sql, params, new BeanPropertyRowMapper<Account>(Account.class)); // 判断根据用户名查找用户是否存在 if (null == account) { log.info("username 是不存在的名字 = " + name); return new UserResult(Code.FAIL, Msg.USER_NOT_EXIST); } } catch (Exception e) { log.error(e, e); if (e instanceof IncorrectResultSizeDataAccessException) { // 没有结果,或者结果数据不符合 account = null; log.info("username 是不存在的名字 = " + name); return new UserResult(Code.FAIL, Msg.USER_NOT_EXIST); } else { return new UserResult(Code.FAIL, Msg.DATA_ACCESS_EXCEPTION); } } log.debug("authorize end."); return new UserResult(Code.SUCCESS, Msg.SUCCESS); }}
XML配置:
<?xml version="1.0" encoding="UTF-8"?><beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd"> <beans:bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <beans:property name="location" value="classpath:c3p0.properties"/> </beans:bean> <beans:bean id="securityDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <beans:property name="driverClass" value="com.mysql.jdbc.Driver" /> <beans:property name="jdbcUrl" value="${jdbc.url}" /> <beans:property name="user" value="${jdbc.username}" /> <beans:property name="password" value="${jdbc.password}" /> </beans:bean> <!-- 用户登录验证 --> <beans:bean class="com.impl.CustomAuthenticationProvider" id="customAuthenticationProvider"> <beans:property name="dataSource" ref="securityDataSource" /> </beans:bean> <!-- 配置静态页面 --> <http pattern="/fonts/**" security="none"/> <http pattern="/js/**" security="none"/> <http pattern="/css/**" security="none"/> <http pattern="/images/**" security="none"/> <!-- 配置不拦截的请求 --> <http auto-config="true" use-expressions="true" create-session="ifRequired"> <intercept-url pattern="/login" access="permitAll" /> <intercept-url pattern="/proxy/*" access="permitAll" /> <intercept-url pattern="/register" access="permitAll" /> <intercept-url pattern="/**" access="hasRole('ROLE_USER')" /> <form-login login-page="/login" default-target-url="/homePage" always-use-default-target="true" /> <logout invalidate-session="true" logout-success-url="/homePage" logout-url="/j_spring_security_logout"/> </http> <authentication-manager> <authentication-provider ref="customAuthenticationProvider" /> </authentication-manager></beans:beans>
除了以上过滤的请求,其余全部会拦截,根据自己需求,进行更改。
可以根据这个配置多个拦截器,赋予它不同的分工。
- SpringMVC HandlerInterceptorAdapter登陆验证拦截器
- SpringMvc拦截器HandlerInterceptorAdapter
- springmvc拦截器HandlerInterceptorAdapter预处理
- springmvc的HandlerInterceptorAdapter拦截器
- SpringMVC拦截器实现登陆时的验证拦截
- springMVC登陆拦截器
- springmvc拦截器用作验证登陆
- springmvc拦截器验证
- 基于注解,HandlerInterceptorAdapter 拦截器
- Spring MVC拦截器HandlerInterceptorAdapter
- SpringMVC 登陆拦截器实现登陆控制
- Spring MVC 中 HandlerInterceptorAdapter的使用[SpringMVC中请求拦截器的实现]
- SpringMVC HandlerInterceptorAdapter
- SpringMVC拦截器(包括自定以拦截器--实现HandlerInterceptorAdapter)(资源和权限管理)
- Spring MVC的拦截器:HandlerInterceptorAdapter
- SpringMvc登陆拦截器的基本使用
- springmvc 全局登陆 拦截器配置
- springmvc拦截器实现登陆认证
- RETINA 屏幕1px 边框实现
- 嗅探
- Robolectric使用
- Tar包解析的内存优化方案
- YTU 1098: The 3n + 1 problem
- SpringMVC HandlerInterceptorAdapter登陆验证拦截器
- java 命令
- Python使用二分插入排序竟然比直接插入排序快99倍!
- 简单创建ASPX(C#)工程
- 我的MYSQL学习心得(七) 查询
- PHP烂代码救星-之上传附件《读thinkphp代码有感》
- MIT算法导论-第13讲-平摊分析
- txt文本行数计算;转为二维数组;二维数组写为txt内容
- Mybatis中的resultType和resultMap