SSO單點登陸系列5:cas單點登陸增長驗證碼功能完整步驟

 

本篇教程cas-server端下載地址:解壓後,直接放到tomcat的webapp目錄下就能用了,不過你須要登陸的話,要修改數據源,C:\tomcat7\webapps\casServer\WEB-INF\deployerConfigContext.xmljavascript


落雨 cas 單點登陸
html


環境:
java

server端:cas-server-core-3.5.2.jar、cas-client-core-3.2.1.jarweb

client端:cas-client-core-3.1.3.jar、http屏蔽了https後的casclient.jar(http://blog.csdn.NET/dengtaowei/article/details/7039399)spring


以前作的界面裏面缺乏一個驗證碼的功能,上週因爲搞其餘事情去了,就沒有開始驗證碼的教程寫做,今天補上,但願能按照教程製做出大家想要的功能。express


結果圖:apache






至此爲止,五篇教程,自定義的Java類不是不少,還不是很深刻。包結構和jar包以下圖,程序去個人csdn下載頻道下載。數組



C:\TOMCAT7\WEBAPPS\CASSERVER\WEB-INF\CLASSES\ORG
└─jasig
    └─cas
        ├─authentication
        │  └─handler
        │      │  CaptchaImageLoginCredentials.class
        │      │  Crypt.class
        │      │  ImageVaditeAuthenticationViaFormAction.class
        │      │  MD5.class
        │      │  RsCasDaoAuthenticationHandler.class
        │      │  
        │      ├─captchaImage
        │      │      CaptchaImageCreateController.class
        │      │      
        │      └─util
        │              ValidatorCodeUtil$ValidatorCode.class
        │              ValidatorCodeUtil.class
        │              
        ├─util
        │      AutowiringSchedulerFactoryBean.class
        │      
        └─web
            │  FlowExecutionExceptionResolver.class
            │  
            └─flow
                    GatewayServicesManagementCheck.class
                    ServiceAuthorizationCheck.class
                    
緩存


 

1.cas-servlet.xml tomcat

.找到C:\tomcat7\webapps\casServer\WEB-INF\cas-servlet.xml文件,在

bean  id="handlerMappingC" 節點下增長


 

[html] view plain copy
  1. <span style="font-family:Microsoft YaHei;font-size:14px;"><bean  
  2.       id="handlerMappingC"  
  3.       class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">  
  4.     <property name="mappings">  
  5.       <props>  
  6.         <prop key="/logout">logoutController</prop>  
  7.         <prop key="/serviceValidate">serviceValidateController</prop>  
  8.         <prop key="/validate">legacyValidateController</prop>  
  9.         <prop key="/proxy">proxyController</prop>  
  10.         <prop key="/proxyValidate">proxyValidateController</prop>  
  11.         <prop key="/samlValidate">samlValidateController</prop>  
  12.         <prop key="/services/add.html">addRegisteredServiceSimpleFormController</prop>  
  13.         <prop key="/services/edit.html">editRegisteredServiceSimpleFormController</prop>  
  14.         <prop key="/services/loggedOut.html">serviceLogoutViewController</prop>  
  15.         <prop key="/services/viewStatistics.html">viewStatisticsController</prop>  
  16.         <prop key="/services/*">manageRegisteredServicesMultiActionController</prop>  
  17.         <prop key="/openid/*">openIdProviderController</prop>  
  18.         <prop key="/authorizationFailure.html">passThroughController</prop>  
  19.         <prop key="/403.html">passThroughController</prop>  
  20.         <prop key="/status">healthCheckController</prop>  
  21.       <!--增長驗證碼的功能-->  
  22.       <prop key="/captcha.htm">captchaImageCreateController</prop>  
  23.                                                              
  24.       </props>  
  25.     </property>  
  26.     <property  
  27.         name="alwaysUseFullPath" value="true"/>  
  28.     <!--  
  29.      uncomment this to enable sending PageRequest events.  
  30.      <property  
  31.        name="interceptors">  
  32.        <list>  
  33.          <ref bean="pageRequestHandlerInterceptorAdapter" />  
  34.        </list>  
  35.      </property>  
  36.       -->  
  37.   </bean></span>  




 

captchaImageCreateController須要咱們本身寫java類

在上述xml代碼後面繼續添加一個bean,以下,而類class路徑是咱們本身寫的,在myeclipse裏面本身diy的包名org.jasig.cas.authentication.handler.captchaImage.CaptchaImageCreateController

[html] view plain copy
  1. <span style="font-family:Microsoft YaHei;font-size:14px;"><!--增長一個bean處理驗證碼-->  
  2. <bean id="captchaImageCreateController"  class="org.jasig.cas.authentication.handler.captchaImage.CaptchaImageCreateController"></bean></span>  




 

2.而後咱們開始寫這個CaptchaImageCreateController類


org.jasig.cas.authentication.handler.captchaImage.CaptchaImageCreateController


CaptchaImageCreateController.java


 

[java] view plain copy
  1. /** 
  2.  * Project Name:casServerHandler 
  3.  * File Name:CaptchaImageCreateController.java 
  4.  * Package Name:org.jasig.cas.authentication.handler.captchaImage 
  5.  * Date:2013-4-28下午03:04:06 
  6.  * Copyright (c) 2013, riambsoft All Rights Reserved. 
  7.  * 
  8.  */  
  9.                                                     
  10. package org.jasig.cas.authentication.handler.captchaImage;  
  11. import java.io.IOException;  
  12.                                                     
  13. import javax.servlet.ServletOutputStream;  
  14. import javax.servlet.http.HttpServletRequest;  
  15. import javax.servlet.http.HttpServletResponse;  
  16.                                                     
  17. import org.jasig.cas.authentication.handler.util.ValidatorCodeUtil;  
  18. import org.jasig.cas.authentication.handler.util.ValidatorCodeUtil.ValidatorCode;  
  19.                                                     
  20. import org.springframework.beans.factory.InitializingBean;  
  21. import org.springframework.web.servlet.ModelAndView;  
  22. import org.springframework.web.servlet.mvc.Controller;  
  23.                                                     
  24. import com.sun.image.codec.jpeg.JPEGCodec;  
  25. import com.sun.image.codec.jpeg.JPEGImageEncoder;  
  26. // import com.wokejia.flow.ValidatorCodeUtil.ValidatorCode;  
  27.                                                     
  28. public class CaptchaImageCreateController implements Controller, InitializingBean {  
  29.                                                         
  30.     public void afterPropertiesSet() throws Exception {  
  31.                                                             
  32.     }  
  33.                                                     
  34.     public ModelAndView handleRequest(HttpServletRequest arg0,  
  35.             HttpServletResponse response) throws Exception {  
  36.         ValidatorCode codeUtil = ValidatorCodeUtil.getCode();  
  37.         System.out.println("code="+codeUtil.getCode());  
  38.                                                             
  39.         arg0.getSession().setAttribute("code", codeUtil.getCode());  
  40.         // 禁止圖像緩存。  
  41.         response.setHeader("Pragma", "no-cache");  
  42.         response.setHeader("Cache-Control", "no-cache");  
  43.         response.setDateHeader("Expires", 0);  
  44.         response.setContentType("image/jpeg");  
  45.                                                     
  46.         ServletOutputStream sos = null;  
  47.         try {  
  48.             // 將圖像輸出到Servlet輸出流中。  
  49.             sos = response.getOutputStream();  
  50.             JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(sos);  
  51.             encoder.encode(codeUtil.getImage());   
  52.             sos.flush();  
  53.             sos.close();  
  54.         } catch (Exception e) {  
  55.         } finally {  
  56.             if (null != sos) {  
  57.                 try {  
  58.                     sos.close();  
  59.                 } catch (IOException e) {  
  60.                     e.printStackTrace();  
  61.                 }  
  62.             }  
  63.         }  
  64.         return null;  
  65.     }  
  66. }  




 

3.開始搞驗證碼圖片生成java類的編寫:

這個類中用到了網上常常用的驗證碼生成類,這個類你能夠本身隨便寫,下面提供一個網上寫的,生成的驗證碼挺漂亮的。


import org.jasig.cas.authentication.handler.util.ValidatorCodeUtil;

import org.jasig.cas.authentication.handler.util.ValidatorCodeUtil.ValidatorCode;


ValidatorCode類是ValidatorCodeUtil類的一個內部類,代碼以下


ValidatorCode.java


 

[java] view plain copy
  1. /** 
  2.  * Project Name:casServerHandler 
  3.  * File Name:ValidatorCodeUtil.java 
  4.  * Package Name:org.jasig.cas.authentication.handler.util 
  5.  * Date:2013-4-28下午03:01:38 
  6.  * Copyright (c) 2013, riambsoft All Rights Reserved. 
  7.  * 
  8.  */  
  9.                                                    
  10. package org.jasig.cas.authentication.handler.util;  
  11.                                                    
  12. import java.awt.Color;  
  13. import java.awt.Font;  
  14. import java.awt.Graphics2D;  
  15. import java.awt.image.BufferedImage;  
  16. import java.util.Random;  
  17. /** 
  18.  * ClassName:ValidatorCodeUtil <br/> Function: TODO ADD FUNCTION. <br/> Reason: TODO ADD REASON. <br/> Date: 2013-4-28 下午03:01:38 <br/> 
  19.  *  
  20.  * @author Administrator 
  21.  * @version 
  22.  * @since JDK 1.5 
  23.  * @see 
  24.  */  
  25. public class ValidatorCodeUtil {  
  26.     public static ValidatorCode getCode() {  
  27.         // 驗證碼圖片的寬度。  
  28.         int width = 80;  
  29.         // 驗證碼圖片的高度。  
  30.         int height = 30;  
  31.         BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);  
  32.         Graphics2D g = buffImg.createGraphics();  
  33.                                                    
  34.         // 建立一個隨機數生成器類。  
  35.         Random random = new Random();  
  36.                                                    
  37.         // 設定圖像背景色(由於是作背景,因此偏淡)  
  38.         g.setColor(Color.WHITE);  
  39.         g.fillRect(0, 0, width, height);  
  40.         // 建立字體,字體的大小應該根據圖片的高度來定。  
  41.         Font font = new Font("微軟雅黑", Font.HANGING_BASELINE, 28);  
  42.         // 設置字體。  
  43.         g.setFont(font);  
  44.                                                    
  45.         // 畫邊框。  
  46.         g.setColor(Color.BLACK);  
  47.         g.drawRect(0, 0, width - 1, height - 1);  
  48.         // 隨機產生155條幹擾線,使圖象中的認證碼不易被其它程序探測到。  
  49.         // g.setColor(Color.GRAY);  
  50.         // g.setColor(getRandColor(160, 200));  
  51.         // for (int i = 0; i < 155; i++) {  
  52.         // int x = random.nextInt(width);  
  53.         // int y = random.nextInt(height);  
  54.         // int xl = random.nextInt(12);  
  55.         // int yl = random.nextInt(12);  
  56.         // g.drawLine(x, y, x + xl, y + yl);  
  57.         // }  
  58.                                                    
  59.         // randomCode用於保存隨機產生的驗證碼,以便用戶登陸後進行驗證。  
  60.         StringBuffer randomCode = new StringBuffer();  
  61.                                                    
  62.         // 設置默認生成4個驗證碼  
  63.         int length = 4;  
  64.         // 設置備選驗證碼:包括"a-z"和數字"0-9"  
  65.         String base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";  
  66.                                                    
  67.         int size = base.length();  
  68.                                                    
  69.         // 隨機產生4位數字的驗證碼。  
  70.         for (int i = 0; i < length; i++) {  
  71.             // 獲得隨機產生的驗證碼數字。  
  72.             int start = random.nextInt(size);  
  73.             String strRand = base.substring(start, start + 1);  
  74.                                                              
  75.             // 用隨機產生的顏色將驗證碼繪製到圖像中。  
  76.             // 生成隨機顏色(由於是作前景,因此偏深)  
  77.             // g.setColor(getRandColor(1, 100));  
  78.                                                                
  79.             // 調用函數出來的顏色相同,多是由於種子太接近,因此只能直接生成  
  80.             g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));  
  81.             g.drawString(strRand, 15 * i + 6, 24);  
  82.                                                    
  83.             // 將產生的四個隨機數組合在一塊兒。  
  84.             randomCode.append(strRand);  
  85.         }  
  86.                                                    
  87.         // 圖象生效  
  88.         g.dispose();  
  89.         ValidatorCode code = new ValidatorCode();  
  90.         code.image = buffImg;  
  91.         code.code = randomCode.toString();  
  92.         return code;  
  93.     }  
  94.                                                    
  95.     // 給定範圍得到隨機顏色  
  96.     static Color getRandColor(int fc, int bc) {  
  97.         Random random = new Random();  
  98.         if (fc > 255)  
  99.             fc = 255;  
  100.         if (bc > 255)  
  101.             bc = 255;  
  102.         int r = fc + random.nextInt(bc - fc);  
  103.         int g = fc + random.nextInt(bc - fc);  
  104.         int b = fc + random.nextInt(bc - fc);  
  105.         return new Color(r, g, b);  
  106.     }  
  107.                                                    
  108.     /** 
  109.      *  
  110.      * <p class="detail"> 
  111.      * 驗證碼圖片封裝 
  112.      * </p> 
  113.      *  
  114.      * @ClassName: ValidatorCode 
  115.      * @version V1.0 
  116.      * @date 2012-4-9 下午07:24:14 
  117.      * @author 羅偉俊 
  118.      *  
  119.      */  
  120.     public static class ValidatorCode {  
  121.         private BufferedImage image;  
  122.         private String code;  
  123.                                                    
  124.         /** 
  125.          * <p class="detail"> 
  126.          * 圖片流 
  127.          * </p> 
  128.          *  
  129.          * @return 
  130.          */  
  131.         public BufferedImage getImage() {  
  132.             return image;  
  133.         }  
  134.                                                    
  135.         /** 
  136.          * <p class="detail"> 
  137.          * 驗證碼 
  138.          * </p> 
  139.          *  
  140.          * @return 
  141.          */  
  142.         public String getCode() {  
  143.             return code;  
  144.         }  
  145.     }  
  146. }  


4.驗證碼生成作完了,那麼咱們開始修改默認的認證器的認證方式,增長驗證碼驗證


本身新建一個java類:


ImageVaditeAuthenticationViaFormAction.java,此類實際上是改造的org.jasig.cas.web.flow.AuthenticationViaFormAction.java這個類,它裏面原本只是驗證用戶名和密碼,咱們增長一個成員變量,code,而後在驗證用戶名和密碼以前,咱們先開始驗證驗證碼。


 

[java] view plain copy
  1. /* 
  2.  * Licensed to Jasig under one or more contributor license 
  3.  * agreements. See the NOTICE file distributed with this work 
  4.  * for additional information regarding copyright ownership. 
  5.  * Jasig licenses this file to you under the Apache License, 
  6.  * Version 2.0 (the "License"); you may not use this file 
  7.  * except in compliance with the License.  You may obtain a 
  8.  * copy of the License at the following location: 
  9.  * 
  10.  *   http://www.apache.org/licenses/LICENSE-2.0 
  11.  * 
  12.  * Unless required by applicable law or agreed to in writing, 
  13.  * software distributed under the License is distributed on an 
  14.  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
  15.  * KIND, either express or implied.  See the License for the 
  16.  * specific language governing permissions and limitations 
  17.  * under the License. 
  18.  */  
  19. package org.jasig.cas.authentication.handler;  
  20.                                        
  21. import javax.servlet.http.HttpServletRequest;  
  22. import javax.servlet.http.HttpServletResponse;  
  23. import javax.validation.constraints.NotNull;  
  24.                                        
  25. import org.jasig.cas.CentralAuthenticationService;  
  26. import org.jasig.cas.authentication.handler.AuthenticationException;  
  27. import org.jasig.cas.authentication.principal.Credentials;  
  28. import org.jasig.cas.authentication.principal.Service;  
  29. import org.jasig.cas.ticket.TicketException;  
  30. import org.jasig.cas.web.bind.CredentialsBinder;  
  31. import org.jasig.cas.web.support.WebUtils;  
  32. import org.slf4j.Logger;  
  33. import org.slf4j.LoggerFactory;  
  34. import org.springframework.binding.message.MessageBuilder;  
  35. import org.springframework.binding.message.MessageContext;  
  36. import org.springframework.util.StringUtils;  
  37. import org.springframework.web.util.CookieGenerator;  
  38. import org.springframework.webflow.execution.RequestContext;  
  39.                                        
  40. /** 
  41.  * Action to authenticate credentials and retrieve a TicketGrantingTicket for those credentials. If there is a request for renew, then it also generates the Service Ticket required. 
  42.  *  
  43.  * @author Scott Battaglia 
  44.  * @version $Revision$ $Date$ 
  45.  * @since 3.0.4 
  46.  */  
  47. public class ImageVaditeAuthenticationViaFormAction {  
  48.                                        
  49.     // 驗證碼參數:  
  50.     private String code = "code";  
  51.                                        
  52.     /** 
  53.      * Binder that allows additional binding of form object beyond Spring defaults. 
  54.      */  
  55.     private CredentialsBinder credentialsBinder;  
  56.                                        
  57.     /** Core we delegate to for handling all ticket related tasks. */  
  58.     @NotNull  
  59.     private CentralAuthenticationService centralAuthenticationService;  
  60.                                        
  61.     @NotNull  
  62.     private CookieGenerator warnCookieGenerator;  
  63.                                        
  64.     protected Logger logger = LoggerFactory.getLogger(getClass());  
  65.                                        
  66.     public final void doBind(final RequestContext context, final Credentials credentials) throws Exception {  
  67.         final HttpServletRequest request = WebUtils.getHttpServletRequest(context);  
  68.                                        
  69.         if (this.credentialsBinder != null && this.credentialsBinder.supports(credentials.getClass())) {  
  70.             this.credentialsBinder.bind(request, credentials);  
  71.         }  
  72.     }  
  73.                                        
  74.     public final String submit(final RequestContext context, final Credentials credentials, final MessageContext messageContext) throws Exception {  
  75.                                        
  76.         // 檢測驗證碼  
  77.         if (credentials instanceof CaptchaImageLoginCredentials) {  
  78.             // 這個類也是咱們本身搞的,裏面能取到驗證碼  
  79.             CaptchaImageLoginCredentials rmupc = (CaptchaImageLoginCredentials) credentials;  
  80.             // 從session中取出生成驗證碼的時候就保存在session中的驗證碼  
  81.             String sessionCode = (String) WebUtils.getHttpServletRequest(context).getSession().getAttribute(code);  
  82.                                        
  83.             // 若是驗證碼爲null  
  84.             if (rmupc.getCode() == null) {  
  85.                 // 寫入日誌  
  86.                 logger.warn("驗證碼爲空");  
  87.                 // 錯誤信息,會在配置文件(messages_zh_CN.properties)裏面先定義好  
  88.                 final String code = "login.code.tip";  
  89.                 // 發送錯誤信息到前臺  
  90.                 messageContext.addMessage(new MessageBuilder().error().code(code).arg("").defaultText(code).build());  
  91.                 return "error";  
  92.             }  
  93.             // 若是驗證碼不正確  
  94.             if (!rmupc.getCode().toUpperCase().equals(sessionCode.toUpperCase())) {  
  95.                 logger.warn("驗證碼檢驗有誤");  
  96.                 final String code = "login.code.error";  
  97.                 messageContext.addMessage(new MessageBuilder().error().code(code).arg("").defaultText(code).build());  
  98.                 return "error";  
  99.             }  
  100.                                        
  101.         }  
  102.                                        
  103.         // Validate login ticket  
  104.         final String authoritativeLoginTicket = WebUtils.getLoginTicketFromFlowScope(context);  
  105.         final String providedLoginTicket = WebUtils.getLoginTicketFromRequest(context);  
  106.         if (!authoritativeLoginTicket.equals(providedLoginTicket)) {  
  107.             this.logger.warn("Invalid login ticket " + providedLoginTicket);  
  108.             final String code = "INVALID_TICKET";  
  109.             messageContext.addMessage(new MessageBuilder().error().code(code).arg(providedLoginTicket).defaultText(code).build());  
  110.             return "error";  
  111.         }  
  112.                                        
  113.         final String ticketGrantingTicketId = WebUtils.getTicketGrantingTicketId(context);  
  114.         final Service service = WebUtils.getService(context);  
  115.         if (StringUtils.hasText(context.getRequestParameters().get("renew")) && ticketGrantingTicketId != null && service != null) {  
  116.                                        
  117.             try {  
  118.                 final String serviceTicketId = this.centralAuthenticationService.grantServiceTicket(ticketGrantingTicketId, service, credentials);  
  119.                 WebUtils.putServiceTicketInRequestScope(context, serviceTicketId);  
  120.                 putWarnCookieIfRequestParameterPresent(context);  
  121.                 return "warn";  
  122.             } catch (final TicketException e) {  
  123.                 if (isCauseAuthenticationException(e)) {  
  124.                     populateErrorsInstance(e, messageContext);  
  125.                     return getAuthenticationExceptionEventId(e);  
  126.                 }  
  127.                                        
  128.                 this.centralAuthenticationService.destroyTicketGrantingTicket(ticketGrantingTicketId);  
  129.                 if (logger.isDebugEnabled()) {  
  130.                     logger.debug("Attempted to generate a ServiceTicket using renew=true with different credentials", e);  
  131.                 }  
  132.             }  
  133.         }  
  134.                                        
  135.         try {  
  136.             WebUtils.putTicketGrantingTicketInRequestScope(context, this.centralAuthenticationService.createTicketGrantingTicket(credentials));  
  137.             putWarnCookieIfRequestParameterPresent(context);  
  138.             return "success";  
  139.         } catch (final TicketException e) {  
  140.             populateErrorsInstance(e, messageContext);  
  141.             if (isCauseAuthenticationException(e))  
  142.                 return getAuthenticationExceptionEventId(e);  
  143.             return "error";  
  144.         }  
  145.     }  
  146.                                        
  147.     private void populateErrorsInstance(final TicketException e, final MessageContext messageContext) {  
  148.                                        
  149.         try {  
  150.             messageContext.addMessage(new MessageBuilder().error().code(e.getCode()).defaultText(e.getCode()).build());  
  151.         } catch (final Exception fe) {  
  152.             logger.error(fe.getMessage(), fe);  
  153.         }  
  154.     }  
  155.                                        
  156.     private void putWarnCookieIfRequestParameterPresent(final RequestContext context) {  
  157.         final HttpServletResponse response = WebUtils.getHttpServletResponse(context);  
  158.                                        
  159.         if (StringUtils.hasText(context.getExternalContext().getRequestParameterMap().get("warn"))) {  
  160.             this.warnCookieGenerator.addCookie(response, "true");  
  161.         } else {  
  162.             this.warnCookieGenerator.removeCookie(response);  
  163.         }  
  164.     }  
  165.                                        
  166.     private AuthenticationException getAuthenticationExceptionAsCause(final TicketException e) {  
  167.         return (AuthenticationException) e.getCause();  
  168.     }  
  169.                                        
  170.     private String getAuthenticationExceptionEventId(final TicketException e) {  
  171.         final AuthenticationException authEx = getAuthenticationExceptionAsCause(e);  
  172.                                        
  173.         if (this.logger.isDebugEnabled())  
  174.             this.logger.debug("An authentication error has occurred. Returning the event id " + authEx.getType());  
  175.                                        
  176.         return authEx.getType();  
  177.     }  
  178.                                        
  179.     private boolean isCauseAuthenticationException(final TicketException e) {  
  180.         return e.getCause() != null && AuthenticationException.class.isAssignableFrom(e.getCause().getClass());  
  181.     }  
  182.                                        
  183.     public final void setCentralAuthenticationService(final CentralAuthenticationService centralAuthenticationService) {  
  184.         this.centralAuthenticationService = centralAuthenticationService;  
  185.     }  
  186.                                        
  187.     /** 
  188.      * Set a CredentialsBinder for additional binding of the HttpServletRequest to the Credentials instance, beyond our default binding of the Credentials as a Form Object in Spring WebMVC parlance. By the time we invoke this CredentialsBinder, we have already engaged in default binding such that for each HttpServletRequest parameter, if there was a JavaBean property of the Credentials implementation of the same name, we have set that property to be the value of the corresponding request parameter. This CredentialsBinder plugin point exists to allow consideration of things other than HttpServletRequest parameters in populating the Credentials (or more sophisticated consideration of the HttpServletRequest parameters). 
  189.      *  
  190.      * @param credentialsBinder 
  191.      *            the credentials binder to set. 
  192.      */  
  193.     public final void setCredentialsBinder(final CredentialsBinder credentialsBinder) {  
  194.         this.credentialsBinder = credentialsBinder;  
  195.     }  
  196.                                        
  197.     public final void setWarnCookieGenerator(final CookieGenerator warnCookieGenerator) {  
  198.         this.warnCookieGenerator = warnCookieGenerator;  
  199.     }  
  200. }  






ImageVaditeAuthenticationViaFormAction.java用到了另外一個類,也是咱們須要改造的類,改造的org.jasig.cas.authentication.principal.UsernamePasswordCredentials.java,你把源碼拿出來和這個類對比一下就知道只是增長了一個private String code;


CaptchaImageLoginCredentials.java


 

[java] view plain copy
  1. /** 
  2.  * Project Name:casServerHandler 
  3.  * File Name:CaptchaImageLoginCredentials.java 
  4.  * Package Name:org.jasig.cas.authentication.handler 
  5.  * Date:2013-4-28下午06:55:08 
  6.  * Copyright (c) 2013, riambsoft All Rights Reserved. 
  7.  * 
  8.  */  
  9.                      
  10. package org.jasig.cas.authentication.handler;  
  11.                      
  12. import java.util.Map;  
  13.                      
  14. import javax.validation.constraints.NotNull;  
  15. import javax.validation.constraints.Size;  
  16.                      
  17. import org.jasig.cas.authentication.principal.RememberMeUsernamePasswordCredentials;  
  18.                      
  19. /** 
  20.  * ClassName:CaptchaImageLoginCredentials <br/> Function: TODO ADD FUNCTION. <br/> Reason: TODO ADD REASON. <br/> Date: 2013-4-28 下午06:55:08 <br/> 
  21.  *  
  22.  * @author Administrator 
  23.  * @version 
  24.  * @since JDK 1.5 
  25.  * @see 
  26.  */  
  27. public class CaptchaImageLoginCredentials extends RememberMeUsernamePasswordCredentials {  
  28.     private static final long serialVersionUID = 1L;  
  29.                      
  30.     private Map<String, Object> param;  
  31.                      
  32.     /** The username. */  
  33.     @NotNull  
  34.     @Size(min = 1, message = "驗證碼爲空")  
  35.     private String code;  
  36.                      
  37.     public String getCode() {  
  38.         return code;  
  39.     }  
  40.                      
  41.     public void setCode(String code) {  
  42.         this.code = code;  
  43.     }  
  44.                      
  45.     public Map<String, Object> getParam() {  
  46.         return param;  
  47.     }  
  48.                      
  49.     public void setParam(Map<String, Object> param) {  
  50.         this.param = param;  
  51.     }  
  52. }  





5.下面開始對xml文件進行修改:


1)仍是剛纔那個路徑,咱們以前修改的xml文件:C:\tomcat7\webapps\casServer\WEB-INF\cas-servlet.xml

[html] view plain copy
  1. <!-- 修改這個bean,變成咱們本身的改造後的類  
  2. <bean id="authenticationViaFormAction" class="org.jasig.cas.web.flow.AuthenticationViaFormAction"  
  3.       p:centralAuthenticationService-ref="centralAuthenticationService"  
  4.       p:warnCookieGenerator-ref="warnCookieGenerator"/>  
  5. -->  
  6.                      
  7. <bean id="authenticationViaFormAction" class="org.jasig.cas.authentication.handler.ImageVaditeAuthenticationViaFormAction"  
  8.       p:centralAuthenticationService-ref="centralAuthenticationService"  
  9.       p:warnCookieGenerator-ref="warnCookieGenerator"/>  
  10.                      
  11. <!-- over -->  



2)C:\tomcat7\webapps\casServer\WEB-INF\login-webflow.xml

 

[html] view plain copy
  1. <flow xmlns="http://www.springframework.org/schema/webflow"  
  2.       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.       xsi:schemaLocation="http://www.springframework.org/schema/webflow  
  4.                           http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">  
  5.                     
  6.    <!-- 替換這個   
  7.     <var name="credentials" class="org.jasig.cas.authentication.principal.UsernamePasswordCredentials" />  
  8.     -->  
  9.     <var name="credentials" class="org.jasig.cas.authentication.handler.CaptchaImageLoginCredentials" />  
  10.                     
  11.     <!-- over -->  
  12.                     
  13.   <on-start>  
  14.         <evaluate expression="initialFlowSetupAction" />  
  15.     </on-start>  



找到節點:viewLoginForm


 

[html] view plain copy
  1. <!-- 修改這個  
  2.    <view-state id="viewLoginForm" view="casLoginView" model="credentials">  
  3.        <binder>  
  4.            <binding property="username" />  
  5.            <binding property="password" />  
  6.        </binder>  
  7.        <on-entry>  
  8.            <set name="viewScope.commandName" value="'credentials'" />  
  9.        </on-entry>  
  10.        <transition on="submit" bind="true" validate="true" to="realSubmit">  
  11.            <evaluate expression="authenticationViaFormAction.doBind(flowRequestContext, flowScope.credentials)" />  
  12.        </transition>  
  13.    </view-state>  
  14. ->  
  15.             
  16.    <view-state id="viewLoginForm" view="casLoginView" model="credentials">  
  17.        <binder>  
  18.            <binding property="username" />  
  19.            <binding property="password" />  
  20.            <binding property="code" />  
  21.             
  22.        </binder>  
  23.        <on-entry>  
  24.            <set name="viewScope.commandName" value="'credentials'" />  
  25.        </on-entry>  
  26.        <transition on="submit" bind="true" validate="true" to="realSubmit">  
  27.            <evaluate expression="authenticationViaFormAction.doBind(flowRequestContext, flowScope.credentials)" />  
  28.        </transition>  
  29.    </view-state>  





 

其實你看到就是增長一個binding屬性code,方便注入到ImageVaditeAuthenticationViaFormAction這個類裏面。

文章末尾會粘貼全部xml文件,以及源碼下載地址

3)在C:\tomcat7\webapps\casServer\WEB-INF\classes最下面添加錯誤提示信息,因爲是使用unicode編碼,因此是看不懂的字符


login.code.tip=\u8BF7\u8F93\u5165\u9A8C\u8BC1\u7801

login.code.error=\u9A8C\u8BC1\u7801\u8F93\u5165\u6709\u8BEF


其實這兩行的意思以下:


login.code.tip=請輸入驗證碼
login.code.error=驗證碼輸入有誤


4)C:\tomcat7\webapps\casServer\WEB-INF\web.xml下新增對URL的處理


 

[html] view plain copy
  1. <!-- validate code-->  
  2.     <servlet-mapping>  
  3.     <servlet-name>cas</servlet-name>  
  4.     <url-pattern>/captcha.htm</url-pattern>  
  5.   </servlet-mapping>  
  6. <!--  over-->  




這一步很重要,不然首頁打開時,根本找不到captacha.htm而不顯示圖片,我作這個的時候,也是搞了很久,才發現web.xml這麼重要的配置忘記寫。


5)如今去找你的前臺頁面C:\tomcat7\webapps\casServer\WEB-INF\view\jsp\default\ui\casLoginView.jsp,給加上驗證碼的文本框和響應事件吧,好比說看不清楚換一張


 

[html] view plain copy
  1. <!-- 驗證碼 -->  
  2.                         <div class="row fl-controls-left">  
  3.                         <label for="code" class="fl-label">驗證碼:</label>  
  4.                                
  5.                         <script type="text/javascript">  
  6.                             function refresh(){  
  7.                          fm1.vali.src="";  
  8.                          fm1.vali.src="captcha.htm";  
  9.                         //img.src='captcha.htm?t='+new Date().getTime()  
  10.                         }  
  11.                     </script>  
  12.                         <input class="required" type="text" tabindex="3"  id="code" size="10"   name="code"  autocomplete="off"  style="float:left;"/>  
  13.                                
  14.                         <div style="height:30px;width:150px;text-align:center;margin-left:5px; float:left;vertical-align:middle; display: table-cell;">  
  15.                         <href="javascript:refresh();" onclick="refresh();"  style="width:130px;height:30px;">  
  16.                                
  17.                         <span style="display: block;float:left;width:60px;height:25px;float:left;">  
  18.                             <img id="vali"  width="60" height="30" src="captcha.htm" style="padding-left: 5px;"/>  
  19.                         </span>  
  20.                          <span style="display:block;width:60px;height:100%;float:left;vertical-align:middle; display: table-cell;margin-left:15px;">看不清楚?換一個</span>  
  21.                         </a>  
  22.                                
  23.                         </div>  





 

ok 大功告成,編譯完的class這幾個文件,通通放入你的server端的各個指定路徑下,重啓tomcat,回帖感謝各位百度前輩吧。


文中所涉及的xml文件完整版:


 下載地址:http://pan.baidu.com/share/link?shareid=439449164&uk=436295647

相關文章
相關標籤/搜索