`

SSO单点登录系列5:cas单点登录增加验证码功能完整步骤

    博客分类:
  • cas
 
阅读更多
 

如果csdn看着不舒服,请移步http://hi.baidu.com/ae6623/item/34f6e23bb424b8342e0f819f,和本系列教程篇同步更新。

 

本篇教程cas-server端下载地址:解压后,直接放到tomcat的webapp目录下就能用了,不过你需要登录的话,要修改数据源,C:\tomcat7\webapps\casServer\WEB-INF\deployerConfigContext.xml,嗯。地址:http://pan.baidu.com/share/link?shareid=439449164&uk=436295647

 

落雨 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:\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 

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

bean  id="handlerMappingC" 节点下增加验证码请求处理<prop key="/captcha.htm">captchaImageCreateController</prop>

 

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  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 plaincopy在CODE上查看代码片派生到我的代码片
 
  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 plaincopy在CODE上查看代码片派生到我的代码片
 
  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 plaincopy在CODE上查看代码片派生到我的代码片
 
  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(00, 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(00, 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 + 624);  
  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 plaincopy在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

 

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  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 plaincopy在CODE上查看代码片派生到我的代码片
 
  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 plaincopy在CODE上查看代码片派生到我的代码片
 
  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 plaincopy在CODE上查看代码片派生到我的代码片
 
  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 plaincopy在CODE上查看代码片派生到我的代码片
 
  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 plaincopy在CODE上查看代码片派生到我的代码片
 
  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.                         <a 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

 

 

 

 

由于是先搞完的程序,后写的文档,所有如有步骤遗漏请及时联系本人,定做详细解答

 

2013年5月13日10:59:48

落雨

qq:394263788

 

 

csdn博客:落雨 :http://blog.csdn.net/ae6623

百度博客:落雨 :http://hi.baidu.com/ae6623/item/34f6e23bb424b8342e0f819f

                           http://hi.baidu.com/ae6623

​参考帖子:http://my.oschina.net/wjgood/blog/90407

 

分享到:
评论

相关推荐

    落雨博客基于CAS框架的单点登录技术讲解(ppt+code实例+doc)配套资料

    [置顶] SSO单点登录系列3:cas-server端配置认证方式实践(数据源+自定义java类认证) http://blog.csdn.net/ae6623/article/details/8851801 [置顶] SSO单点登录系列2:cas客户端和cas服务端交互原理动画图解,cas...

    Java进阶SSO单点登录技术CAS-快速上手与原理探究视频教程

    本课程主要通过CAS来实现SSO,本教程会从最基本的基础知识讲起,由浅入深再到实战,完成多应用的单点登录功能。 本课程内容如下: 1、 什么是SSO和CAS 2、 CAS Server服务端和客户端的搭建和配置 3、 单点登录和单...

    PHP 使用TP5.0 实现SSO单点登录

    因为公司要实现SSO单点登录的效果,最近在网上找了一些资料,但是都没有好用的, 所以自己用PHP 使用TP5.0 实现了SSO单点登录,可以跨多个域名。 下载后在本地配置好 A,B,C 3个网站,就可以模拟效果了。

    CAS实现sso单点登录原理

    CAS实现sso单点登录原理,可以方便技术人员理解

    sso单点登录ppt.ppt

    sso单点登录ppt.ppt

    CAS_SSO单点登录实例详细步骤

    CAS_SSO单点登录实例详细步骤,CAS_,SSO,单点登录

    单点登录sso-shiro-cas-maven

    spring下使用shiro+cas配置单点登录,多个系统之间的访问,每次只需要登录一次 ## 系统模块说明 1. cas: 单点登录模块,这里直接拿的是cas的项目改了点样式而已 2. doc: 文档目录,里面有数据库生成语句,采用的...

    单点登录demo

    单点登录

    转载CAS_SSO单点登录实例详细步骤

    CAS_SSO单点登录实例详细步骤,讲解的非常详细

    SSO单点登录

    ASP.NET跨域单点登录源码 asp.net 跨域单点登录实现原理: 当用户第一次访问web应用系统1的时候,因为还没有登录,会被引导到认证中心进行登录; 根据用户提供的登录信息,认证系统进行身份效验,如果 通过效验,...

    sso单点登录源代码

    sso单点登录源代码sso单点登录源代码sso单点登录源代码sso单点登录源代码sso单点登录源代码

    spring boot 实现SSO单点登陆

    spring boot整合spring security 实现SSO单点登陆 完整DEMO. 1、配置本地hosts 127.0.0.1 sso-login 127.0.0.1 sso-resource 127.0.0.1 sso-tmall 127.0.0.1 sso-taobao windows系统的路径在C:\WINDOWS\system...

    baigo SSO单点登录系统 v3.0.1.zip

    baigo SSO单点登录系统 v3.0.1更新日志 增加数据清理功能 baigo SSO单点登录系统简介 baigo SSO 是一款基于 HTTP 协议的单点登录系统,baigo SSO 以简单为设计、开发的宗旨,安装部署简单、使用简单。baigo SSO ...

    单点登录: 仿CAS sso.zip

    单点登录: 仿CAS。实现了单点登录功能。访问 http://localhost:8090/ssoClient/index/index 或者 http://localhost:8090/ssoClient/login 进行登录 登录成功后会跳转到 ...

    CAS单点登录(SSO)教程

    单点登录(Single Sign On , 简称 SSO )是目前比较流行的服务于企业业务整合的解决方案之一, SSO 使得在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。CAS(Central Authentication ...

    CAS_SSO单点登录实例详细步骤.doc

    CAS_SSO单点登录实例详细步骤.doc CAS_SSO单点登录实例详细步骤.doc

    SSO单点登陆解决方案

    一个实现SSO方案的构想SSO单点登陆解决方案

    CAS jasig SSO单点登录解决方案完整版

    cas-client-core-3.2.1.jar LoginImpl.java LoginServlet.java SSOClientFilter.java web.xml 电子政务平台单点登录集成手册v4.0-2017年2月9日.docx

Global site tag (gtag.js) - Google Analytics