spring security3 扩充验证码
spring security3 扩展验证码security的登录参数验证主要是经过UsernamePasswordAuthenticationFilter过滤
spring security3 扩展验证码
security的登录参数验证主要是经过UsernamePasswordAuthenticationFilter过滤器
?
所以我们自己写个新的实现类类继承UsernamePasswordAuthenticationFilter,验证码工具我是使用jcaptcha,相信大家对这个也不会感觉陌生吧,至于网上也有很多这样的例子来演示如何扩展了
?
先来写个实现类继承UsernamePasswordAuthenticationFilter
?
[java] view plaincopy
- /**??*?重载SECURITY3的UsernamePasswordAuthenticationFilter的attemptAuthentication,?
- ?*?obtainUsername,obtainPassword方法(完善逻辑)?增加验证码校验模块?添加验证码属性?添加验证码功能开关属性??*??
- ?*?@author?shadow??*?@email?124010356@qq.com?
- ?*?@create?2012.04.28??*/??
- public?class?UsernamePasswordAuthenticationExtendFilter?extends??????????UsernamePasswordAuthenticationFilter?{??
- ??????//?验证码字段??
- ????private?String?validateCodeParameter?=?"validateCode";??????//?是否开启验证码功能??
- ????private?boolean?openValidateCode?=?false;????
- ????@Override??????public?Authentication?attemptAuthentication(HttpServletRequest?request,??
- ????????????HttpServletResponse?response)?throws?AuthenticationException?{??????????//?只接受POST方式传递的数据??
- ????????if?(!"POST".equals(request.getMethod()))??????????????throw?new?MethodErrorException("不支持非POST方式的请求!");??
- ??????????//?开启验证码功能的情况??
- ????????if?(isOpenValidateCode())??????????????checkValidateCode(request);??
- ??????????//?获取Username和Password??
- ????????String?username?=?obtainUsername(request);??????????String?password?=?obtainPassword(request);??
- ??????????//?UsernamePasswordAuthenticationToken实现Authentication校验??
- ????????UsernamePasswordAuthenticationToken?authRequest?=?new?UsernamePasswordAuthenticationToken(??????????????????username,?password);??
- ??????????//?允许子类设置详细属性??
- ????????setDetails(request,?authRequest);????
- ????????//?运行UserDetailsService的loadUserByUsername?再次封装Authentication??????????return?this.getAuthenticationManager().authenticate(authRequest);??
- ????}????
- ????//?匹对验证码的正确性??????public?void?checkValidateCode(HttpServletRequest?request)?{??
- ??????????String?jcaptchaCode?=?obtainValidateCodeParameter(request);??
- ????????if?(null?==?jcaptchaCode)??????????????throw?new?ValidateCodeException("验证码超时,请重新获取!");??
- ??????????boolean?b?=?CaptchaServiceSingleton.getInstance()??
- ????????????????.validateResponseForID(request.getSession().getId(),??????????????????????????jcaptchaCode);??
- ????????if?(!b)??????????????throw?new?ValidateCodeException("验证码不正确,请重新输入!");??
- ????}????
- ????public?String?obtainValidateCodeParameter(HttpServletRequest?request)?{??????????Object?obj?=?request.getParameter(getValidateCodeParameter());??
- ????????return?null?==?obj???""?:?obj.toString().trim();??????}??
- ??????@Override??
- ????protected?String?obtainUsername(HttpServletRequest?request)?{??????????Object?obj?=?request.getParameter(getUsernameParameter());??
- ????????return?null?==?obj???""?:?obj.toString().trim();??????}??
- ??????@Override??
- ????protected?String?obtainPassword(HttpServletRequest?request)?{??????????Object?obj?=?request.getParameter(getPasswordParameter());??
- ????????return?null?==?obj???""?:?obj.toString().trim();??????}??
- ??????public?String?getValidateCodeParameter()?{??
- ????????return?validateCodeParameter;??????}??
- ??????public?void?setValidateCodeParameter(String?validateCodeParameter)?{??
- ????????this.validateCodeParameter?=?validateCodeParameter;??????}??
- ??????public?boolean?isOpenValidateCode()?{??
- ????????return?openValidateCode;??????}??
- ??????public?void?setOpenValidateCode(boolean?openValidateCode)?{??
- ????????this.openValidateCode?=?openValidateCode;??????}??
- ??}??
很明显我们在获取username跟password之前执行一个checkValidateCode()的方法,这里就是先比较验证码,如果失败就直接抛出ValidateCodeException,这个异常自己定义个,
?
只要继承AuthenticationException就可以了
?
?
?
校验成功就直接往下执行比较username,password,然后配置xml的时候class的指向就用自己新的filter,过滤链中使用新 的filter替换掉UsernamePasswordAuthenticationFilter实现类的位置,下面是我自己的xml配置
?
过滤链里的serverCustomUsernamePasswordAuthenticationFilter实现换成是我们自己刚写的实现类,至于com.shadow.security.handler.LoginSuccessHandler和
?
com.shadow.security.handler.LoginFailureHandler这里自己实现一个AuthenticationSuccessHandler接口里面逻辑根据项目需求来设计
?
[java] view plaincopy
- <!--?登录认证过滤器-->??????<bean?id="usernamePasswordAuthenticationFilter"??
- ????????class="com.shadow.security.service.UsernamePasswordAuthenticationExtendFilter">??????????<property?name="authenticationManager"??
- ????????????ref="authenticationManager"?/>??????????<property?name="sessionAuthenticationStrategy"??
- ????????????ref="concurrentSessionControlStrategy"?/>??????????<property?name="usernameParameter"?value="username"?/>??
- ????????<property?name="passwordParameter"?value="password"?/>??????????<property?name="validateCodeParameter"?value="validateCode"?/>??
- ????????<property?name="openValidateCode"?value="true"?/>??????????<property?name="filterProcessesUrl"?value="/login"?/>??
- ????????<property?name="rememberMeServices"?ref="rememberMeServices"?/>??????????<property?name="authenticationSuccessHandler">??
- ????????????<bean??????????????????class="com.shadow.security.handler.LoginSuccessHandler">??
- ????????????????<property?name="indexUrl"?value="/index.jsp"?/>??????????????</bean>??
- ????????</property>??????????<property?name="authenticationFailureHandler">??
- ????????????<bean??????????????????class="com.shadow.security.handler.LoginFailureHandler"?/>??
- ????????</property>??????</bean>??
?
至于其他的依赖属性注入就自己根据项目来添加吧,这里就不详细说明了