`
kong0itey
  • 浏览: 298990 次
社区版块
存档分类
最新评论

SpringSecurity3.X--验证码(转载)

阅读更多

一般来说,登录时都会要求用户输入验证码,以防止恶意登录。

可是,SpringSecurity并没有为我们提供这样的功能,所以就需要我们自己来解决了。

那么该如何解决呢,其实也挺简单的,

核对验证码信息,当然是在登录时处理的,所以,使用filter是最佳选择。

 

既然确定了方向,那么久该考虑如何增加这个filter了,其实可以有两种方案:

1.继承UsernamePasswordAuthenticationFilter ,在里面增加验证码验证规则即可;

2.自己定义一个filter,专门处理验证码验证;

 

笔者这里推荐使用第二种方案,因为第一种我们需要显示声明login-filter,所以需要修改SpringSecurity的配置文件,而方案 2根本不需要修改,只需要向一般的filter一样,在web.xml中增加配置即可,唯一需要注意的是,mapping一定要与触发login- filter的url一致,如下所示:

Xml代码  收藏代码
  1. < filter >   
  2.         < filter-name > imageFilter </ filter-name >   
  3.         < filter-class > com.piaoyi.common.filter.ImageFilter </ filter-class >   
  4.           
  5.     </ filter >   
  6.     < filter-mapping >   
  7.         < filter-name > imageFilter </ filter-name >   
  8.         < url-pattern > /j_spring_security_check </ url-pattern >   
  9.     </ filter-mapping >   

另外需要注意的是,该filter的mapping一定要声明在springSecurityFilterChain的mapping之前,这样可以保证请求先被imageFilter处理。

 

设计思路就是这样的,这里给出一个简单的实现。

 

login.jsp

Html代码  收藏代码
  1. < %@ page  language = "java"   contentType = "text/html; charset=UTF-8"   
  2.     pageEncoding = "UTF-8" % >   
  3. < %@ include  file = "/WEB-INF/views/jsp/common/includes.jsp" % >   
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">   
  5. < html >   
  6. < head >   
  7. < meta   http-equiv = "Content-Type"   content = "text/html; charset=UTF-8" >   
  8. < title > 登陆 </ title >   
  9. </ head >   
  10. < body >   
  11.   
  12.     < center >   
  13.         < div   class = "error" >   
  14.             ${sessionScope.SPRING_SECURITY_LAST_EXCEPTION.message }</ div >   
  15.         < form   name = 'f'   id = 'f'   
  16.             action = '<%=request.getContextPath()%>/j_spring_security_check'   
  17.             method = 'POST' >   
  18.             < table   style = "width: 50%" >   
  19.                 < tr >   
  20.                     < td   style = "text-align: right; width: 35%" > 用户名称 : </ td >   
  21.                     < td   style = "text-align: left" > < input   type = 'text'   
  22.                         name = 'j_username'   value = '' > </ td >   
  23.                 </ tr >   
  24.                 < tr >   
  25.                     < td   style = "text-align: right" > 密码 : </ td >   
  26.                     < td   style = "text-align: left" > < input   type = 'password'   
  27.                         name = 'j_password'   /> </ td >   
  28.                 </ tr >   
  29.                 < tr >   
  30.                     < td   style = "text-align: right" > < label   for = "j_captcha" >  验证码:  </ label > </ td >   
  31.                     < td >   
  32.                     < input   type = 'text'   name = 'j_captcha'   class = "required"   
  33.                         size = '5'   />   
  34.                         < img   id = "imageF"   src = "<c:url value=" /resource/image.jsp" /> />   
  35.                     < a   href = "#"   id = "flashImage" > 看不清楚换一张 </ a >   
  36.                       
  37.                     </ td >   
  38.                 </ tr >   
  39.                 < tr >   
  40.                     < td   align = "right" > < input   id = "_spring_security_remember_me"   
  41.                         name = "_spring_security_remember_me"   type = "checkbox"   value = "true"   />   
  42.   
  43.                     </ td >   
  44.                     < td > < label   for = "_spring_security_remember_me" > Remember Me? </ label >   
  45.                     </ td >   
  46.                 </ tr >   
  47.                 < tr >   
  48.                     < td   colspan = "2"   style = "text-align: center" > < input   
  49.                         type = "submit"   name = "submit"   value = "登录"   /> </ td >   
  50.                 </ tr >   
  51.             </ table >   
  52.         </ form >   
  53.     </ center >   
  54.     < script   type = "text/javascript" >   
  55.       
  56.         document.f.j_username.focus();  
  57.         if ('${message}' == 1) {  
  58.             alert("用户名或密码错误");  
  59.         }  
  60.           
  61.         jQuery(function($){  
  62.               
  63.       
  64.             $("#flashImage").click(function(){  
  65.                   
  66.                 $('#imageF').hide().attr('src','< c:url   value = "/resource/image.jsp" /> '+ '?'+ Math.floor(Math.random() * 100)).fadeIn();  
  67.             });  
  68.         });  
  69.           
  70.           
  71.     </ script >   
  72.   
  73.   
  74. </ body >   
  75. </ html >   

 ImageFilter.java

Java代码  收藏代码
  1. package  com.piaoyi.common.filter;  
  2.   
  3. import  java.io.IOException;  
  4.   
  5. import  javax.servlet.Filter;  
  6. import  javax.servlet.FilterChain;  
  7. import  javax.servlet.FilterConfig;  
  8. import  javax.servlet.ServletException;  
  9. import  javax.servlet.ServletRequest;  
  10. import  javax.servlet.ServletResponse;  
  11. import  javax.servlet.http.HttpServletRequest;  
  12. import  javax.servlet.http.HttpServletResponse;  
  13.   
  14. public   class  ImageFilter  implements  Filter{  
  15.   
  16.     @Override   
  17.     public   void  destroy() {  
  18.         // TODO Auto-generated method stub   
  19.           
  20.     }  
  21.   
  22.     @Override   
  23.     public   void  doFilter(ServletRequest arg0, ServletResponse arg1,  
  24.             FilterChain arg2) throws  IOException, ServletException {  
  25.         // TODO Auto-generated method stub   
  26.         HttpServletRequest request = (HttpServletRequest) arg0;    
  27.         HttpServletResponse response = (HttpServletResponse) arg1;   
  28.           
  29.         String yanzhengm = request.getParameter("j_captcha" );  
  30.         String sessionyanz = (String)request.getSession(true ).getAttribute( "yzkeyword" );  
  31.         if (yanzhengm.equals(sessionyanz)){  
  32.             arg2.doFilter(request, response);   
  33.         }else {  
  34.             response.sendRedirect("/login.do" );  
  35.         }  
  36.     }  
  37.   
  38.     @Override   
  39.     public   void  init(FilterConfig arg0)  throws  ServletException {  
  40.         // TODO Auto-generated method stub   
  41.           
  42.     }  
  43.   
  44.       
  45. }  

 image.jsp

Html代码  收藏代码
  1. < %@ page  contentType = "image/jpeg"   import = "java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*"   pageEncoding = "UTF-8" % >   
  2. < %!  
  3. Color getRandColor(int fc,int bc){//随机获得颜色,RGB格式  
  4.         Random random  =  new  Random();  
  5.         if(fc> 255)  fc = 255 ;  
  6.         if(bc> 255)  bc = 255 ;  
  7.         int r = fc +random.nextInt(bc-fc);  
  8.         int g = fc +random.nextInt(bc-fc);  
  9.         int b = fc +random.nextInt(bc-fc);  
  10.         return new Color(r,g,b);  
  11.         }  
  12. %>   
  13. < %  
  14. //清除缓存,每次访问该页面时都从服务器端读取  
  15. response.setHeader("Pragma","No-cache");  
  16. response.setHeader("Cache-Control","no-cache");  
  17. response.setDateHeader("Expires", 0);  
  18.   
  19. // 定义显示图片的宽度和高度  
  20. int width = 60 height = 20 ;  
  21. BufferedImage image  =  new  BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);  
  22.   
  23. // 画图画板  
  24. Graphics g  =  image .getGraphics();  
  25.   
  26. //定义一个随机数  
  27. Random random  =  new  Random();  
  28.   
  29. // 设置画板背景颜色  
  30. g.setColor(getRandColor(200,250));  
  31. //设置画板的填充范围  
  32. g.fillRect(0, 0, width, height);  
  33.   
  34. //设置字体  
  35. g.setFont(new Font("Times New Roman",Font.PLAIN,18));  
  36.   
  37. // 设置线条颜色并画线,155条  
  38. g.setColor(getRandColor(160,200));  
  39. for (int i = 0 ;i < 155 ;i++)  
  40. {  
  41.  int x  =  random .nextInt(width);  
  42.  int y  =  random .nextInt(height);  
  43.         int xl  =  random .nextInt(12);  
  44.         int yl  =  random .nextInt(12);  
  45.  g.drawLine(x,y,x+xl,y+yl);  
  46. }  
  47.   
  48. // 显示数字,4位长度  
  49. String sRand = "" ;  
  50. for (int i = 0 ;i < 4 ;i++){  
  51.     String rand = String .valueOf(random.nextInt(10));  
  52.     sRand+=rand;  
  53.     // 设置每个数字的颜色  
  54.     g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));  
  55. //在画板上写数字,起始位置  
  56.     g.drawString(rand,13*i+6,16);  
  57. }  
  58.   
  59. // 保存进session  
  60. session.setAttribute("yzkeyword",sRand);  
  61. //System.out.println("yzm:"+sRand);  
  62.   
  63.   
  64. // 显示图片  
  65. g.dispose();  
  66.   
  67. %>   
  68.   
  69. < %  
  70. //转换成一张图片,格式为JPEG  
  71. ImageIO.write(image, "JPEG", response.getOutputStream());  
  72. out.clear();//清空缓存的内容。  
  73.   
  74. pageContext.pushBody();  
  75. %>   
 

applicationContext-security.xml

Xml代码  收藏代码
  1. <? xml   version = "1.0"   encoding = "UTF-8" ?>   
  2. < beans:beans   xmlns = "http://www.springframework.org/schema/security"   
  3.     xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"   xmlns:p = "http://www.springframework.org/schema/p"   
  4.     xmlns:aop = "http://www.springframework.org/schema/aop"   xmlns:context = "http://www.springframework.org/schema/context"   
  5.     xmlns:jee = "http://www.springframework.org/schema/jee"   xmlns:tx = "http://www.springframework.org/schema/tx"   
  6.     xmlns:util = "http://www.springframework.org/schema/util"   xmlns:mvc = "http://www.springframework.org/schema/mvc"   
  7.     xmlns:tool = "http://www.springframework.org/schema/tool"   xmlns:beans = "http://www.springframework.org/schema/beans"   
  8.     xsi:schemaLocation ="  
  9.             http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd  
  10.             http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  
  11.             http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd  
  12.             http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd  
  13.             http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd  
  14.             http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd  
  15.             http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd  
  16.             http://www.springframework.org/schema/tool http://www.springframework.org/schema/tool/spring-tool-3.1.xsd  
  17.             http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"  
  18.     default-lazy-init = "true" >   
  19.   
  20.   
  21.     < http   security = "none"   pattern = "/index.do"   />   
  22.   
  23.   
  24.     < http   auto-config = 'true'   access-decision-manager-ref = "accessDecisionManager"   
  25.         access-denied-page = "/index.do" >   
  26.         < intercept-url   pattern = "/demo.do*"   access = "IS_AUTHENTICATED_REMEMBERED"   />   
  27.         < intercept-url   pattern = "/**/*.do*"   access = "HODLE"   />   
  28.         < logout   logout-url = "/logout.do"   invalidate-session = "true"   
  29.             logout-success-url = "/logout.jsp"   />   
  30.         < form-login   login-page = "/index.do"   default-target-url = "/frame.do"   
  31.             always-use-default-target = "true"   authentication-failure-url = "/index.do?login_error=1"   />   
  32.         < session-management >   
  33.             < concurrency-control   max-sessions = "1"   expired-url = "/timeout.jsp" />   
  34.         </ session-management >   
  35.           
  36.         < remember-me   key = "jbcpPetStore"   />    
  37.     </ http >   
  38.   
  39.   
  40.   
  41.     <!-- Automatically receives AuthenticationEvent messages -->   
  42.     < beans:bean   id = "loggerListener"   
  43.         class = "org.springframework.security.authentication.event.LoggerListener"   />   
  44.   
  45.     < authentication-manager   erase-credentials = "false" >   
  46.         < authentication-provider   user-service-ref = "userService" >   
  47.             < password-encoder   hash = "md5"   />   
  48.         </ authentication-provider >   
  49.     </ authentication-manager >   
  50.   
  51.     < beans:bean   id = "userService"   class = "com.piaoyi.common.security.UserService"   />   
  52.   
  53.     < beans:bean   id = "accessDecisionManager"   
  54.         class = "org.springframework.security.access.vote.AffirmativeBased" >   
  55.         < beans:property   name = "decisionVoters" >   
  56.             < beans:list >   
  57.                 < beans:bean   class = "org.springframework.security.access.vote.RoleVoter"   />   
  58.                 < beans:bean   
  59.                     class = "org.springframework.security.access.vote.AuthenticatedVoter"   />   
  60.                 < beans:bean   class = "com.piaoyi.common.security.DynamicRoleVoter"   />   
  61.             </ beans:list >   
  62.         </ beans:property >   
  63.     </ beans:bean >   
  64. </ beans:beans >   

 效果图如下:

 

 

另外,从网上也看到了类似的解决方案:

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics