zoukankan      html  css  js  c++  java
  • SSO单点登录系列5:cas单点登录增加验证码功能完整步骤

     

    本篇教程cas-server端下载地址:解压后,直接放到tomcat的webapp目录下就能用了,不过你需要登录的话,要修改数据源,C: omcat7webappscasServerWEB-INFdeployerConfigContext.xml


    落雨 cas 单点登录


    环境:

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

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


    之前做的界面里面缺少一个验证码的功能,上周由于搞其他事情去了,就没有开始验证码的教程写作,今天补上,希望能按照教程制作出你们想要的功能。


    结果图:






    至此为止,五篇教程,自定义的Java类不是很多,还不是很深入。包结构和jar包如下图,程序去我的csdn下载频道下载。



    C:TOMCAT7WEBAPPSCASSERVERWEB-INFCLASSESORG
    └─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 

    .找到C: omcat7webappscasServerWEB-INFcas-servlet.xml文件,在

    bean  id="handlerMappingC" 节点下增加


     

    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

    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


     

    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


    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,然后在验证用户名和密码之前,我们先开始验证验证码。


    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


     

    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: omcat7webappscasServerWEB-INFcas-servlet.xml

    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: omcat7webappscasServerWEB-INFlogin-webflow.xml

     

    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


     

    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: omcat7webappscasServerWEB-INFclasses最下面添加错误提示信息,由于是使用unicode编码,所以是看不懂的字符


    login.code.tip=u8BF7u8F93u5165u9A8Cu8BC1u7801

    login.code.error=u9A8Cu8BC1u7801u8F93u5165u6709u8BEF


    其实这两行的意思如下:


    login.code.tip=请输入验证码
    login.code.error=验证码输入有误


    4)C: omcat7webappscasServerWEB-INFweb.xml下新增对URL的处理


     

    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: omcat7webappscasServerWEB-INFviewjspdefaultuicasLoginView.jsp,给加上验证码的文本框和响应事件吧,比如说看不清楚换一张


    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;150px;text-align:center;margin-left:5px; float:left;vertical-align:middle; display: table-cell;">  
    15.                         <href="javascript:refresh();" onclick="refresh();"  style="130px;height:30px;">  
    16.                                
    17.                         <span style="display: block;float:left;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;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

  • 相关阅读:
    OI算法复习汇总
    B. Anatoly and Cockroaches
    c# 文件过大时清空原有内容重新写入
    c# 记录内容到txt文件
    c# 关闭和重启.exe程序
    mutex 互斥量
    mysql 事件
    <asp:Button点击查询后,调用js中函数展现加载圈
    取得<asp:TextBox中的值:
    json 相关知识
  • 原文地址:https://www.cnblogs.com/austinspark-jessylu/p/6899744.html
Copyright © 2011-2022 走看看