有三中方法可以实现验证码的功能

第一种是自定义一个filter,放在SpringSecurity过滤器之前,在用户登录的时候会先经过这个filter,然后在这个filter中实现对验证码进行验证的功能,这种方法不推荐,因为它已经脱离了SpringSecurity

第二种是自定义一个filter让它继承自UsernamePasswordAuthenticationFilter,然后重写attemptAuthentication方法在这个方法中实现验证码的功能,如果验证码错误就抛出一个继承自AuthenticationException的验证吗错误的异常比如(CaptchaException),然后这个异常就会被SpringSecurity捕获到并将异常信息返回到前台,这种实现起来比较简单

  1. @Override
  2. public Authentication attemptAuthentication(HttpServletRequest request,
  3. HttpServletResponse response) throws AuthenticationException {
  4. String requestCaptcha = request.getParameter(this.getCaptchaFieldName());
  5. String genCaptcha = (String)request.getSession().getAttribute("code");
  6. logger.info("开始校验验证码,生成的验证码为:"+genCaptcha+" ,输入的验证码为:"+requestCaptcha);
  7. if( !genCaptcha.equals(requestCaptcha)){
  8. throw new CaptchaException(
  9. this.messageSource.getMessage("AbstractUserDetailsAuthenticationProvider.badCaptcha",null,"Default",null));
  10. }
  11. return super.attemptAuthentication(request, response);
  12. }

然后在配置文件中配置下

  1. <bean id="loginFilter" class="com.zrhis.system.security.DefaultUsernamePasswordAuthenticationFilter">
  2. <property name="authenticationManager"  ref="authenticationManager"></property>
  3. <property name="authenticationSuccessHandler">
  4. <bean class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
  5. <property name="defaultTargetUrl" value="/index.jsp"></property>
  6. </bean>
  7. </property>
  8. <property name="authenticationFailureHandler">
  9. <bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
  10. <property name="defaultFailureUrl" value="/login.jsp"></property>
  11. </bean>
  12. </property>
  13. </bean>

最后在http中加入custom-filter配置,将这个filter放在SpringSecurity的FORM_LOGIN_FILTER之前

  1. <custom-filter ref="loginFilter" before="FORM_LOGIN_FILTER"/>

最后一种是直接替换掉SpringSecurity的UsernamePasswordAuthenticationFilter,这种比较复杂,但是更为合理,也是我现在正在用的。

如果用这种方法那么http 中的auto-config就必须去掉,而form-login配置也必须去掉,因为这个不需要了,里面的属性都需要我们自行注入。

首先需要创建一个EntryPoint

  1. <bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
  2. <property name="loginFormUrl" value="/login.jsp" />
  3. </bean>

然后在http中配置下

  1. <sec:http access-decision-manager-ref="accessDecisionManager"
  2. entry-point-ref="authenticationEntryPoint">

然后我们来写CaptchaAuthenticationFilter,同样需要继承自UsernamePasswordAuthenticationFilter

  1. public class CaptchaAuthenticationFilter extends UsernamePasswordAuthenticationFilter{
  2. public static final String SPRING_SECURITY_FORM_CAPTCHA_KEY = "j_captcha";
  3. public static final String SESSION_GENERATED_CAPTCHA_KEY = Constant.SESSION_GENERATED_CAPTCHA_KEY;
  4. private String captchaParameter = SPRING_SECURITY_FORM_CAPTCHA_KEY;
  5. public Authentication attemptAuthentication(HttpServletRequest request,
  6. HttpServletResponse response) throws AuthenticationException {
  7. String genCode = this.obtainGeneratedCaptcha(request);
  8. String inputCode = this.obtainCaptcha(request);
  9. if(genCode == null)
  10. throw new CaptchaException(this.messages.getMessage("LoginAuthentication.captchaInvalid"));
  11. if(!genCode.equalsIgnoreCase(inputCode)){
  12. throw new CaptchaException(this.messages.getMessage("LoginAuthentication.captchaNotEquals"));
  13. }
  14. return super.attemptAuthentication(request, response);
  15. }
  16. protected String obtainCaptcha(HttpServletRequest request){
  17. return request.getParameter(this.captchaParameter);
  18. }
  19. protected String obtainGeneratedCaptcha (HttpServletRequest request){
  20. return (String)request.getSession().getAttribute(SESSION_GENERATED_CAPTCHA_KEY);
  21. }
  22. }

在配置文件中配置CaptchaAuthenticationFilter

  1. <bean id="captchaAuthenticaionFilter" class="com.zrhis.system.security.CaptchaAuthenticationFilter">
  2. <property name="authenticationManager" ref="authenticationManager" />
  3. <property name="authenticationFailureHandler" ref="authenticationFailureHandler" />
  4. <property name="authenticationSuccessHandler" ref="authenticationSuccessHandler" />
  5. <property name="filterProcessesUrl" value="/login.do" />
  6. </bean>
  7. <bean id="authenticationSuccessHandler" class="com.zrhis.system.security.SimpleLoginSuccessHandler">
  8. <property name="defaultTargetUrl" value="/WEB-INF/app.jsp"></property>
  9. <property name="forwardToDestination" value="true"></property>
  10. </bean>
  11. <bean id="authenticationFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
  12. <property name="defaultFailureUrl" value="/login.jsp" />
  13. </bean>

从配置文件中就可以看出来authenticationManager、authenticationFailureHandler、authenticationSuccessHandler、filterProcessesUrl等都需要我们自行注入了。

filterProcessesUrl定义的是登录验证的地址,默认的是j_spring_security_check这里我们改成login.do

authenticationSuccessHandler中的defaultTargetUrl定义的是登录成功后跳转到的页面

authenticationFailureHandler中的defaultTargetUrl定义的是登录失败后跳转到的页面

我们的首页app.jsp在/WEB-INF下所以需要使用服务器跳转,所以需要将forwardToDestination设为true,因为客户端跳转是不能直接访问WEB-INF下的内容的。

最后在http中将FORM_LOGIN_FILTER替换掉,最终http中完整的配置就变成了下面的内容

  1. <sec:http access-decision-manager-ref="accessDecisionManager"
  2. entry-point-ref="authenticationEntryPoint">
  3. <sec:access-denied-handler ref="accessDeniedHandler"/>
  4. <sec:session-management invalid-session-url="/login.jsp" />
  5. <sec:custom-filter ref="filterSecurityInterceptor" before="FILTER_SECURITY_INTERCEPTOR"/>
  6. <sec:custom-filter ref="captchaAuthenticaionFilter" position="FORM_LOGIN_FILTER"/>
  7. </sec:http>

custom-filter中before是在这个filter之前,after是之后,position是替换。

这样就可以实现对验证码的验证了,效果如下

Spring Security教程 ---- 验证码功能的实现的更多相关文章

  1. Spring Security教程(五):自定义过滤器从数据库从获取资源信息

    在之前的几篇security教程中,资源和所对应的权限都是在xml中进行配置的,也就在http标签中配置intercept-url,试想要是配置的对象不多,那还好,但是平常实际开发中都往往是非常多的资 ...

  2. 临远的spring security教程

    为啥选择Spring Security 欢迎阅读咱们写的Spring Security教程,咱们既不想写一个简单的入门教程,也不想翻译已有的国外教程.咱们这个教程就是建立在咱们自己做的OA的基础上,一 ...

  3. Spring Security 教程 大牛的教程

    https://www.iteye.com/blog/elim-2247073 Spring Security 教程 Spring Security(20)——整合Cas Spring Securit ...

  4. Spring Security教程(八):用户认证流程源码详解

    本篇文章主要围绕下面几个问题来深入源码: 用户认证流程 认证结果如何在多个请求之间共享 获取认证用户信息 一.用户认证流程 上节中提到Spring Security核心就是一系列的过滤器链,当一个请求 ...

  5. Spring Security教程(三):自定义表结构

    在上一篇博客中讲解了用Spring Security自带的默认数据库存储用户和权限的数据,但是Spring Security默认提供的表结构太过简单了,其实就算默认提供的表结构很复杂,也不一定能满足项 ...

  6. Spring Security教程(二):通过数据库获得用户权限信息

    上一篇博客中,Spring Security教程(一):初识Spring Security,我把用户信息和权限信息放到了xml文件中,这是为了演示如何使用最小的配置就可以使用Spring Securi ...

  7. [转载]spring security 的 logout 功能

    原文地址:security 的 logout 功能">spring security 的 logout 功能作者:sumnny 转载自:http://lengyun3566.iteye ...

  8. Spring Security教程(三)

    在上一篇博客中讲解了用Spring Security自带的默认数据库存储用户和权限的数据,但是Spring Security默认提供的表结构太过简单了,其实就算默认提供的表结构很复杂,也不一定能满足项 ...

  9. Spring Security教程(二)

    上一篇博客中,Spring Security教程(一),我把用户信息和权限信息放到了xml文件中,这是为了演示如何使用最小的配置就可以使用Spring Security,而实际开发中,用户信息和权限信 ...

随机推荐

  1. 修复Win10下Synaptics触摸板双指触击无法打开右键菜单的问题

    从Win8.1开始,Synaptics触摸板驱动的键值就不能正确设置,使得双指触击失效,无法打开右键菜单. 解决方法1.打开注册表:2.搜索“2FingerTapAction”,或直接定位到以下两个路 ...

  2. golang模板语法简明教程

    [模板标签] 模板标签用"{{"和"}}"括起来   [注释] {{/* a comment */}} 使用“{{/*”和“*/}}”来包含注释内容   [变量 ...

  3. hive 字符集问题 报错 Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. MetaException(message:For direct MetaStore DB connections,

    学习hive 使用mysql作为元数据  hive创建数据库和切换数据库都是可以的 但是创建表就是出问题 百度之后发现 是编码问题 特别记录一下~~~ 1.报错前如图: 2.在mysql数据库中执行如 ...

  4. dom4j api 详解

    1.DOM4J简介 DOM4J是 dom4j.org 出品的一个开源 XML 解析包.DOM4J应用于 Java 平台,采用了 Java 集合框架并完全支持 DOM,SAX 和 JAXP. DOM4J ...

  5. 描述J2EE框架的多层结构,并简要说明各层的作用。

    描述J2EE框架的多层结构,并简要说明各层的作用. 解答: 1) Presentation layer(表示层) a. 表示逻辑(生成界面代码) b. 接收请求 c. 处理业务层抛出的异常 d. 负责 ...

  6. git 入门一(初识)

    分布式版本控制系统 & 集中式版本控制系统   分布式版本控制系统( Distributed Version Control System)在这类系统中,像 Git,Mercurial,Baz ...

  7. Linux USB 鼠标输入驱动具体解释

    平台:mini2440 内核:linux 2.6.32.2 USB设备插入时.内核会读取设备信息,接着就把id_table里的信息与读取到的信息做比較.看是否匹配,假设匹配.就调用probe函数. U ...

  8. Python入门(六):标准库

    操作系统接口 os模块提供了不少与操作系统相关联的函数. import os os.getcwd() # 返回当前的工作目录 os.chdir('d:/') # 修改当前的工作目录 os.system ...

  9. web之Django之Form组件

    Django之Form组件 本节内容 基本使用 form中字段和插件 自定义验证规则 动态加载数据到form中 1. 基本使用 django中的Form组件有以下几个功能: 生成HTML标签 验证用户 ...

  10. 5秒后跳转到另一个页面的js代码

    今天看视频学习时学习了一种新技术,即平时我们在一个页面点击“提交”或“确认”会自动跳转到一个页面. 在网上搜了一下,关于这个技术处理有多种方法,我只记下我在视频里学到的三种: 1.用一个respons ...