spring security进级篇VI JCaptcha验证编码的使用

在spring security中,可以结合jcaptcha进行使用,具体方法如下:

1.java类如下:

Java代码   收藏代码
  1. package  com.spring.security.jcaptcha;  
  2.   
  3. import  java.awt.Color;  
  4. import  java.awt.Font;  
  5. import  java.awt.image.ImageFilter;  
  6.   
  7. import  com.octo.captcha.component.image.backgroundgenerator.BackgroundGenerator;  
  8. import  com.octo.captcha.component.image.backgroundgenerator.UniColorBackgroundGenerator;  
  9. import  com.octo.captcha.component.image.color.RandomListColorGenerator;  
  10. import  com.octo.captcha.component.image.deformation.ImageDeformation;  
  11. import  com.octo.captcha.component.image.deformation.ImageDeformationByFilters;  
  12. import  com.octo.captcha.component.image.fontgenerator.FontGenerator;  
  13. import  com.octo.captcha.component.image.fontgenerator.RandomFontGenerator;  
  14. import  com.octo.captcha.component.image.textpaster.DecoratedRandomTextPaster;  
  15. import  com.octo.captcha.component.image.textpaster.TextPaster;  
  16. import  com.octo.captcha.component.image.textpaster.textdecorator.TextDecorator;  
  17. import  com.octo.captcha.component.image.wordtoimage.DeformedComposedWordToImage;  
  18. import  com.octo.captcha.component.image.wordtoimage.WordToImage;  
  19. import  com.octo.captcha.component.word.FileDictionary;  
  20. import  com.octo.captcha.component.word.wordgenerator.ComposeDictionaryWordGenerator;  
  21. import  com.octo.captcha.component.word.wordgenerator.WordGenerator;  
  22. import  com.octo.captcha.engine.image.ListImageCaptchaEngine;  
  23. import  com.octo.captcha.image.gimpy.GimpyFactory;  
  24.   
  25. /**  
  26.  * JCaptcha验证码图片生成引擎, 仿照JCaptcha2.0编写类似GMail验证码的样式.  
  27.  */   
  28. public   class  GMailEngine  extends  ListImageCaptchaEngine {  
  29.   
  30.     @Override   
  31.     protected   void  buildInitialFactories() {  
  32.   
  33.         // 图片和字体大小设置   
  34.         int  minWordLength =  4 ;  
  35.         int  maxWordLength =  5 ;  
  36.         int  fontSize =  20 ;  
  37.         int  imageWidth =  100 ;  
  38.         int  imageHeight =  36 ;  
  39.   
  40.         WordGenerator dictionnaryWords = new  ComposeDictionaryWordGenerator(  
  41.                 new  FileDictionary( "toddlist" ));  
  42.   
  43.         // word2image components   
  44.         TextPaster randomPaster = new  DecoratedRandomTextPaster(minWordLength,  
  45.                 maxWordLength, new  RandomListColorGenerator( new  Color[] {  
  46.                         new  Color( 23 170 27 ),  new  Color( 220 34 11 ),  
  47.                         new  Color( 23 67 172 ) }),  new  TextDecorator[] {});  
  48.         BackgroundGenerator background = new  UniColorBackgroundGenerator(  
  49.                 imageWidth, imageHeight, Color.white);  
  50.         FontGenerator font = new  RandomFontGenerator(fontSize, fontSize,  
  51.                 new  Font[] {  new  Font( "nyala" , Font.BOLD, fontSize),  
  52.                         new  Font( "Bell MT" , Font.PLAIN, fontSize),  
  53.                         new  Font( "Credit valley" , Font.BOLD, fontSize) });  
  54.           
  55.         ImageDeformation postDef = new  ImageDeformationByFilters(  
  56.                 new  ImageFilter[] {});  
  57.         ImageDeformation backDef = new  ImageDeformationByFilters(  
  58.                 new  ImageFilter[] {});  
  59.         ImageDeformation textDef = new  ImageDeformationByFilters(  
  60.                 new  ImageFilter[] {});  
  61.   
  62.         WordToImage word2image = new  DeformedComposedWordToImage(font,  
  63.                 background, randomPaster, backDef, textDef, postDef);  
  64.           
  65.         addFactory(new  GimpyFactory(dictionnaryWords, word2image));  
  66.     }  
  67.   
  68. }  

过滤器如下:

Java代码   收藏代码
  1. package  com.spring.security.jcaptcha;  
  2.   
  3. import  java.awt.image.BufferedImage;  
  4. import  java.io.IOException;  
  5.   
  6. import  javax.imageio.ImageIO;  
  7. import  javax.servlet.Filter;  
  8. import  javax.servlet.FilterChain;  
  9. import  javax.servlet.FilterConfig;  
  10. import  javax.servlet.ServletException;  
  11. import  javax.servlet.ServletOutputStream;  
  12. import  javax.servlet.ServletRequest;  
  13. import  javax.servlet.ServletResponse;  
  14. import  javax.servlet.http.HttpServletRequest;  
  15. import  javax.servlet.http.HttpServletResponse;  
  16.   
  17. import  org.apache.commons.lang.StringUtils;  
  18. import  org.apache.log4j.Logger;  
  19. import  org.springframework.context.ApplicationContext;  
  20. import  org.springframework.web.context.support.WebApplicationContextUtils;  
  21.   
  22. import  com.octo.captcha.service.CaptchaService;  
  23. import  com.octo.captcha.service.CaptchaServiceException;  
  24.   
  25. /**  
  26.  * 针对 JCaptcha 专门的过滤器(Filter)  
  27.  *   
  28.  */   
  29. public   class  JCaptchaFilter  implements  Filter {  
  30.   
  31.     // web.xml中的参数名定义   
  32.     public   static   final  String PARAM_CAPTCHA_PARAMTER_NAME =  "captchaParamterName" ;  
  33.     public   static   final  String PARAM_CAPTCHA_SERVICE_ID =  "captchaServiceId" ;  
  34.     public   static   final  String PARAM_FILTER_PROCESSES_URL =  "filterProcessesUrl" ;  
  35.     public   static   final  String PARAM_FAILURE_URL =  "failureUrl" ;  
  36.     public   static   final  String PARAM_AUTO_PASS_VALUE =  "autoPassValue" ;  
  37.   
  38.     // 默认值定义   
  39.     public   static   final  String DEFAULT_FILTER_PROCESSES_URL =  "/j_spring_security_check" ;  
  40.     public   static   final  String DEFAULT_CAPTCHA_SERVICE_ID =  "captchaService" ;  
  41.     public   static   final  String DEFAULT_CAPTCHA_PARAMTER_NAME =  "j_captcha" ;  
  42.   
  43.     protected   static  Logger logger = Logger.getLogger( "service" );  
  44.   
  45.     private  String failureUrl;  
  46.     private  String filterProcessesUrl = DEFAULT_FILTER_PROCESSES_URL;  
  47.     private  String captchaServiceId = DEFAULT_CAPTCHA_SERVICE_ID;  
  48.     private  String captchaParamterName = DEFAULT_CAPTCHA_PARAMTER_NAME;  
  49.     private  String autoPassValue;  
  50.   
  51.     private  CaptchaService captchaService;  
  52.   
  53.     /**  
  54.      * Filter回调初始化函数.  
  55.      */   
  56.     public   void  init(FilterConfig filterConfig)  throws  ServletException {  
  57.         // TODO Auto-generated method stub   
  58.           
  59.         initParameters(filterConfig);  
  60.         initCaptchaService(filterConfig);  
  61.     }  
  62.   
  63.     public   void  doFilter(ServletRequest theRequest,ServletResponse theResponse, FilterChain chain)  throws  IOException,  
  64.             ServletException {  
  65.           
  66.         HttpServletRequest request = (HttpServletRequest) theRequest;  
  67.         HttpServletResponse response = (HttpServletResponse) theResponse;  
  68.         String servletPath = request.getServletPath();  
  69.           
  70.         // 符合filterProcessesUrl为验证处理请求,其余为生成验证图片请求.   
  71.         if  (StringUtils.startsWith(servletPath, filterProcessesUrl)) {  
  72.             boolean  validated = validateCaptchaChallenge(request);  
  73.             if  (validated) {  
  74.                 chain.doFilter(request, response);  
  75.             } else  {  
  76.                 redirectFailureUrl(request, response);  
  77.             }  
  78.         } else  {  
  79.             genernateCaptchaImage(request, response);  
  80.         }  
  81.     }  
  82.   
  83.     /**  
  84.      * Filter回调退出函数.  
  85.      */   
  86.     public   void  destroy() {  
  87.         // TODO Auto-generated method stub   
  88.     }  
  89.   
  90.     /**  
  91.      * 初始化web.xml中定义的filter init-param.  
  92.      */   
  93.     protected   void  initParameters( final  FilterConfig fConfig) {  
  94.           
  95.         if  (StringUtils.isBlank(fConfig.getInitParameter(PARAM_FAILURE_URL))) {  
  96.             throw   new  IllegalArgumentException( "CaptchaFilter缺少failureUrl参数" );  
  97.         }  
  98.   
  99.         failureUrl = fConfig.getInitParameter(PARAM_FAILURE_URL);  
  100.   
  101.         if  (StringUtils.isNotBlank(fConfig  
  102.                 .getInitParameter(PARAM_FILTER_PROCESSES_URL))) {  
  103.             filterProcessesUrl = fConfig  
  104.                     .getInitParameter(PARAM_FILTER_PROCESSES_URL);  
  105.         }  
  106.   
  107.         if  (StringUtils.isNotBlank(fConfig  
  108.                 .getInitParameter(PARAM_CAPTCHA_SERVICE_ID))) {  
  109.             captchaServiceId = fConfig  
  110.                     .getInitParameter(PARAM_CAPTCHA_SERVICE_ID);  
  111.         }  
  112.   
  113.         if  (StringUtils.isNotBlank(fConfig  
  114.                 .getInitParameter(PARAM_CAPTCHA_PARAMTER_NAME))) {  
  115.             captchaParamterName = fConfig  
  116.                     .getInitParameter(PARAM_CAPTCHA_PARAMTER_NAME);  
  117.         }  
  118.   
  119.         if  (StringUtils.isNotBlank(fConfig  
  120.                 .getInitParameter(PARAM_AUTO_PASS_VALUE))) {  
  121.             autoPassValue = fConfig.getInitParameter(PARAM_AUTO_PASS_VALUE);  
  122.         }  
  123.     }  
  124.   
  125.     /**  
  126.      * 从ApplicatonContext获取CaptchaService实例.  
  127.      */   
  128.     protected   void  initCaptchaService( final  FilterConfig fConfig) {  
  129.           
  130.         ApplicationContext context = WebApplicationContextUtils  
  131.                 .getWebApplicationContext(fConfig.getServletContext());  
  132.         captchaService = (CaptchaService) context.getBean(captchaServiceId);  
  133.     }  
  134.   
  135.     /**  
  136.      * 生成验证码图片.  
  137.      */   
  138.     protected   void  genernateCaptchaImage( final  HttpServletRequest request,  
  139.             final  HttpServletResponse response)  throws  IOException {  
  140.   
  141.         setDisableCacheHeader(response);  
  142.         response.setContentType("image/jpeg" );  
  143.   
  144.         ServletOutputStream out = response.getOutputStream();  
  145.         try  {  
  146.             String captchaId = request.getSession(true ).getId();  
  147.             BufferedImage challenge = (BufferedImage) captchaService  
  148.                     .getChallengeForID(captchaId, request.getLocale());  
  149.             ImageIO.write(challenge, "jpg" , out);  
  150.             out.flush();  
  151.         } catch  (CaptchaServiceException e) {  
  152.             logger.error(e.getMessage(), e);  
  153.         } finally  {  
  154.             if (out!= null ){  
  155.                 out.close();  
  156.             }  
  157.         }  
  158.     }  
  159.   
  160.     /**  
  161.      * 验证验证码.  
  162.      */   
  163.     protected   boolean  validateCaptchaChallenge( final  HttpServletRequest request) {  
  164.           
  165.         try  {  
  166.               
  167.             String captchaID = request.getSession().getId();  
  168.             String challengeResponse = request  
  169.                     .getParameter(captchaParamterName);  
  170.             // 自动通过值存在时,检验输入值是否等于自动通过值   
  171.             if  (StringUtils.isNotBlank(autoPassValue)&& autoPassValue.equals(challengeResponse)) {  
  172.                   
  173.                 return   true ;  
  174.             }  
  175.               
  176.             return  captchaService.validateResponseForID(captchaID,challengeResponse);  
  177.         } catch  (CaptchaServiceException e) {  
  178.             logger.error(e.getMessage(), e);  
  179.             return   false ;  
  180.         }  
  181.     }  
  182.   
  183.     /**  
  184.      * 跳转到失败页面.  
  185.      *   
  186.      * 可在子类进行扩展, 比如在session中放入SpringSecurity的Exception.  
  187.      */   
  188.     protected   void  redirectFailureUrl( final  HttpServletRequest request, final  HttpServletResponse response)  throws  IOException {  
  189.           
  190.         response.sendRedirect(request.getContextPath() + failureUrl);  
  191.     }  
  192.   
  193.     /**  
  194.      * 设置禁止客户端缓存的Header.  
  195.      */   
  196.     public   static   void  setDisableCacheHeader(HttpServletResponse response) {  
  197.         // Http 1.0 header   
  198.         response.setDateHeader("Expires" , 1L);  
  199.         response.addHeader("Pragma" "no-cache" );  
  200.         // Http 1.1 header   
  201.         response.setHeader("Cache-Control" "no-cache, no-store, max-age=0" );  
  202.     }  
  203. }  

web.xml 配置如下:

Xml代码   收藏代码
  1. <? xml   version = "1.0"   encoding = "UTF-8" ?>   
  2. < web-app   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"   xmlns = "http://java.sun.com/xml/ns/javaee"   xmlns:web = "http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"   xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"   id = "WebApp_ID"   version = "2.5" >   
  3.   < display-name > springSecurityIII </ display-name >   
  4.     
  5.     <!--******************************** -->   
  6.     <!--*******log4j日志信息的配置****** -->   
  7.     <!--******************************* -->   
  8.     < context-param >   
  9.         < param-name > log4jConfigLocation </ param-name >   
  10.         < param-value > classpath:log4j.xml </ param-value >   
  11.     </ context-param >   
  12.     <!--Spring默认刷新Log4j配置文件的间隔,单位为millisecond,可以不设置 -->   
  13.     < context-param >   
  14.         < param-name > log4jRefreshInterval </ param-name >   
  15.         < param-value > 60000 </ param-value >   
  16.     </ context-param >   
  17.   
  18.     <!--******************************** -->   
  19.     <!--*******spring bean的配置******** -->   
  20.     <!--******************************* -->   
  21.     < context-param >   
  22.         < param-name > contextConfigLocation </ param-name >   
  23.         < param-value > classpath:applicationContext.xml </ param-value >   
  24.     </ context-param >   
  25.       
  26.     < listener >   
  27.         < listener-class > org.springframework.web.util.Log4jConfigListener </ listener-class >   
  28.     </ listener >   
  29.     < listener >   
  30.         < listener-class > org.springframework.web.context.ContextLoaderListener </ listener-class >   
  31.     </ listener >   
  32.     < listener >   
  33.         < listener-class > org.springframework.web.util.IntrospectorCleanupListener </ listener-class >   
  34.     </ listener >   
  35.       
  36.     <!--******************************** -->   
  37.     <!--*******字符集 过滤器************ -->   
  38.     <!--******************************* -->   
  39.     < filter >   
  40.         < filter-name > CharacterEncodingFilter </ filter-name >   
  41.         < filter-class > org.springframework.web.filter.CharacterEncodingFilter </ filter-class >   
  42.         < init-param >   
  43.             < param-name > encoding </ param-name >   
  44.             < param-value > UTF-8 </ param-value >   
  45.         </ init-param >   
  46.         < init-param >   
  47.             < param-name > forceEncoding </ param-name >   
  48.             < param-value > true </ param-value >   
  49.         </ init-param >   
  50.     </ filter >   
  51.     < filter-mapping >   
  52.         < filter-name > CharacterEncodingFilter </ filter-name >   
  53.         < url-pattern > /* </ url-pattern >   
  54.     </ filter-mapping >   
  55.   
  56.     <!--******************************** -->   
  57.     <!--*******session的配置************ -->   
  58.     <!--******************************* -->   
  59.     < session-config >   
  60.         < session-timeout > 30 </ session-timeout >   
  61.     </ session-config >   
  62.       
  63.   < filter >   
  64.     < filter-name > jcaptchaFilter </ filter-name >   
  65.     < filter-class > com.spring.security.jcaptcha.JCaptchaFilter </ filter-class >   
  66.     < init-param >   
  67.       < param-name > failureUrl </ param-name >   
  68.       < param-value > /login.jsp </ param-value >   
  69.     </ init-param >   
  70.   </ filter >   
  71.   < filter-mapping >   
  72.     < filter-name > jcaptchaFilter </ filter-name >   
  73.     < url-pattern > /jcaptcha.jpg </ url-pattern >   
  74.   </ filter-mapping >   
  75.   < filter-mapping >   
  76.     < filter-name > jcaptchaFilter </ filter-name >   
  77.     < url-pattern > /j_spring_security_check </ url-pattern >   
  78.   </ filter-mapping >   
  79.   < filter >   
  80.     < filter-name > springSecurityFilterChain </ filter-name >   
  81.     < filter-class > org.springframework.web.filter.DelegatingFilterProxy </ filter-class >   
  82.   </ filter >   
  83.     
  84.   < filter-mapping >   
  85.     < filter-name > springSecurityFilterChain </ filter-name >   
  86.     < url-pattern > /* </ url-pattern >   
  87.   </ filter-mapping >   
  88.   < listener >   
  89.     < listener-class > org.springframework.security.web.session.HttpSessionEventPublisher </ listener-class >   
  90.   </ listener >   
  91.     
  92.   < welcome-file-list >   
  93.     < welcome-file > index.jsp </ welcome-file >   
  94.   </ welcome-file-list >   
  95. </ web-app >   

login.jsp

Java代码   收藏代码
  1. <%@ include file= "/common/taglibs.jsp" %>  
  2. <%@ page language="java"  contentType= "text/html; charset=UTF-8"   
  3.     pageEncoding="UTF-8" %>  
  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. <script type="text/javascript" >  
  10.   
  11. /*==============================================  
  12. *   refreash the captcha to general new picture  
  13. *==============================================*/   
  14. function refreshCaptcha() {     
  15.     $('#captchaImg' ).hide().attr(     
  16.     'src' ,     
  17.     '<c:url value="/jcaptcha.jpg"/>'  +  '?'  + Math.floor(Math.random() *  100 )).fadeIn();     
  18. }  
  19. </script>  
  20. </head>  
  21. <body>  
  22.     <center>  
  23.         <div class = "login-error" >  
  24.             ${sessionScope.SPRING_SECURITY_LAST_EXCEPTION.message}  
  25.         </div>  
  26.         <form action="${pageContext.request.contextPath}/j_spring_security_check"  method= "post" >  
  27.             <table style="width: 60%" >  
  28.                 <tr>  
  29.                     <td>用户名:</td>  
  30.                     <td>  
  31.                         <input class  =  "login-smallInput"  type= 'text'  name= 'j_username' />  
  32.                     </td>  
  33.                 </tr>  
  34.                 <tr>  
  35.                     <td>密 &nbsp;&nbsp;码:</td>  
  36.                     <td>  
  37.                         <input class  =  "login-smallInput"  type= 'password'  name= 'j_password'  />  
  38.                     </td>  
  39.                 </tr>  
  40.                 <tr>  
  41.                     <td>验证码:</td>  
  42.                     <td>  
  43.                         <input type='text'  name= 'j_captcha'  size= "5" />   
  44.                         <img id="captchaImg"  style= "vertical-align:middle"  src= "<c:url value=" /jcaptcha.jpg "/>"  />   
  45.                         <a href="javascript:refreshCaptcha()" >看不清楚换一张</a>  
  46.                     </td>  
  47.                 </tr>  
  48.                 <tr>  
  49.                     <td>  
  50.                         <input id="_spring_security_remember_me"  name= "_spring_security_remember_me"  type= "checkbox" />  
  51.                     </td>  
  52.                     <td>  
  53.                         <label for = "_spring_security_remember_me" >Remember Me?</label>  
  54.                     </td>  
  55.                 </tr>  
  56.                 <tr>  
  57.                     <td colspan="2" >  
  58.                         <input type="submit"  name= "submit"  value= "登录"  />  
  59.                     </td>  
  60.                 </tr>  
  61.             </table>  
  62.         </form>  
  63.     </center>  
  64. </body>  
  65. </html> 

猜你喜欢

转载自marsvaadin.iteye.com/blog/1736546