CAS添加验证码功能

1.  cas.war 下面的web-inf/web.xml  lib添加  kaptcha.jar

  kaptcha.jar通过maven获取

 <dependency>
    <groupId>com.github.axet</groupId>
    <artifactId>kaptcha</artifactId>
    <version>0.0.9</version>
 </dependency>

这个maven 包含两个 jar 另一个是filters-2.0.235.jar

2. cas.war 下面的web-inf/web.xml添加验证码映射

<servlet>  
        <servlet-name>Kaptcha</servlet-name>  
        <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>  
        <init-param>  
            <param-name>kaptcha.border</param-name>  
            <param-value>no</param-value>  
        </init-param>  
        <init-param>  
            <param-name>kaptcha.textproducer.char.space</param-name>  
            <param-value>5</param-value>  
        </init-param>  
        <init-param>  
            <param-name>kaptcha.textproducer.char.length</param-name>  
            <param-value>5</param-value>  
        </init-param>  
    </servlet>  
      
    <servlet-mapping>  
        <servlet-name>Kaptcha</servlet-name>  
        <url-pattern>/captcha.jpg</url-pattern>  
</servlet-mapping>  

3. cas中 UsernamePasswordCredentials 类增加验证码属性 authcode

/** The authcode. */  
   @NotNull  
   @Size(min=1, message = "required.authcode")  
   private String authcode;  
     
public String getAuthcode() {  
    return authcode;  
}  
  
public void setAuthcode(String authcode) {  
    this.authcode = authcode;  
}  
  
/** 
    * @return Returns the password. 
    */  
   public final String getPassword() {  
       return this.password;  
   }  

并且重写equals和hashCode方法

@Override  
   public boolean equals(final Object o) {  
       if (this == o) return true;  
       if (o == null || getClass() != o.getClass()) return false;  
  
       UsernamePasswordCredentials that = (UsernamePasswordCredentials) o;  
  
       if (password != null ? !password.equals(that.password) : that.password != null) return false;  
       if (username != null ? !username.equals(that.username) : that.username != null) return false;  
       if (authcode != null ? !authcode.equals(that.authcode) : that.authcode != null) return false;  
       return true;  
   }  
  
   @Override  
   public int hashCode() {  
       int result = username != null ? username.hashCode() : 0;  
       result = 31 * result + (password != null ? password.hashCode() : 0);  
       result = 31 * result + (authcode != null ? authcode.hashCode() : 0);  
       return result;  
   }  

4. AuthenticationViaFormAction 类增加验证方法

public final String validatorCode(final RequestContext context,  final Credentials credentials, final MessageContext messageContext) throws Exception {   
        final HttpServletRequest request = WebUtils.getHttpServletRequest(context);  
        HttpSession session = request.getSession();  
        String authcode = (String)session.getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);  
        session.removeAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);  
          
        UsernamePasswordCredentials upc = (UsernamePasswordCredentials)credentials;  
        String submitAuthcode =upc.getAuthcode();  
        if(!StringUtils.hasText(submitAuthcode) || !StringUtils.hasText(authcode)){  
            populateErrorsInstance(new NullAuthcodeAuthenticationException(),messageContext);  
            return "error";    
        }  
        if(submitAuthcode.equals(authcode)){    
            return "success";  
        }  
        populateErrorsInstance(new BadAuthcodeAuthenticationException(),messageContext);  
        return "error";    
    }  

NullAuthcodeAuthenticationException 、BadAuthcodeAuthenticationException为定义的异常类,取得异常编码

/* 
 * Licensed to Jasig under one or more contributor license 
 * agreements. See the NOTICE file distributed with this work 
 * for additional information regarding copyright ownership. 
 * Jasig licenses this file to you under the Apache License, 
 * Version 2.0 (the "License"); you may not use this file 
 * except in compliance with the License.  You may obtain a 
 * copy of the License at the following location: 
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, 
 * software distributed under the License is distributed on an 
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
 * KIND, either express or implied.  See the License for the 
 * specific language governing permissions and limitations 
 * under the License. 
 */  
package org.jasig.cas.authentication.handler;  
  
import org.jasig.cas.ticket.TicketException;  
  
/** 
 * The exception to throw when we know the authcode is null 
 *  
 * @author Scott Battaglia 
 * @version $Revision$ $Date$ 
 * @since 3.0 
 */  
public class NullAuthcodeAuthenticationException extends TicketException {  
      
    /** Serializable ID for unique id. */  
    private static final long serialVersionUID = 5501212207531289993L;  
  
    /** Code description. */  
    public static final String CODE = "required.authcode";  
  
    /** 
     * Constructs a TicketCreationException with the default exception code. 
     */  
    public NullAuthcodeAuthenticationException() {  
        super(CODE);  
    }  
  
    /** 
     * Constructs a TicketCreationException with the default exception code and 
     * the original exception that was thrown. 
     *  
     * @param throwable the chained exception 
     */  
    public NullAuthcodeAuthenticationException(final Throwable throwable) {  
        super(CODE, throwable);  
    }}  
/* 
 * Licensed to Jasig under one or more contributor license 
 * agreements. See the NOTICE file distributed with this work 
 * for additional information regarding copyright ownership. 
 * Jasig licenses this file to you under the Apache License, 
 * Version 2.0 (the "License"); you may not use this file 
 * except in compliance with the License.  You may obtain a 
 * copy of the License at the following location: 
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, 
 * software distributed under the License is distributed on an 
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
 * KIND, either express or implied.  See the License for the 
 * specific language governing permissions and limitations 
 * under the License. 
 */  
package org.jasig.cas.authentication.handler;  
  
import org.jasig.cas.ticket.TicketException;  
  
/** 
 * The exception to throw when we know the authcoe is not correct 
 *  
 * @author Scott Battaglia 
 * @version $Revision$ $Date$ 
 * @since 3.0 
 */  
public class BadAuthcodeAuthenticationException extends TicketException {  
      
    /** Serializable ID for unique id. */  
    private static final long serialVersionUID = 5501212207531289993L;  
  
    /** Code description. */  
    public static final String CODE = "error.authentication.authcode.bad";  
  
    /** 
     * Constructs a TicketCreationException with the default exception code. 
     */  
    public BadAuthcodeAuthenticationException() {  
        super(CODE);  
    }  
  
    /** 
     * Constructs a TicketCreationException with the default exception code and 
     * the original exception that was thrown. 
     *  
     * @param throwable the chained exception 
     */  
    public BadAuthcodeAuthenticationException(final Throwable throwable) {  
        super(CODE, throwable);  
    }}  

5. login_webflow.xml 修改登录验证流程

<view-state id="viewLoginForm" view="casLoginView" model="credentials">  
        <binder>  
            <binding property="username" />  
            <binding property="password" />  
            <binding property="authcode" />  
        </binder>  
        <on-entry>  
            <set name="viewScope.commandName" value="'credentials'" />  
        </on-entry>  
        <transition on="submit" bind="true" validate="true" to="authcodeValidate">  
            <evaluate expression="authenticationViaFormAction.doBind(flowRequestContext, flowScope.credentials)" />  
        </transition>  
    </view-state>  
  
    <action-state id="authcodeValidate">    
        <evaluate expression="authenticationViaFormAction.validatorCode(flowRequestContext, flowScope.credentials, messageContext)" />    
        <transition on="error" to="generateLoginTicket" />    
        <transition on="success" to="realSubmit" />    
    </action-state> 

6. 增加国际化显示信息

messages_zh_CN.properties文件中添加,其他国家语言类似添加

screen.welcome.label.authcode=u9A8Cu8BC1u7801:  
screen.welcome.label.authcode.accesskey=a  
required.authcode=u5FC5u987Bu5F55u5165u9A8Cu8BC1u7801u3002  
error.authentication.authcode.bad=u9A8Cu8BC1u7801u8F93u5165u6709u8BEFu3002  

7. 登录页面casLoginView.jsp添加验证码输入框

<div class="row fl-controls-left">  
                      <label for="authcode"><spring:message code="screen.welcome.label.authcode" /></label>  
                      <spring:message code="screen.welcome.label.authcode.accesskey" var="authcodeAccessKey" />  
                        <table>  
                        <tr>  
                                <td>  
                        <form:input cssClass="required" cssErrorClass="error" id="authcode" size="10" tabindex="2" path="authcode"  accesskey="${authcodeAccessKey}" htmlEscape="true" autocomplete="off" />  
                        </td>  
                                <td align="left" valign="bottom" style="vertical-align: bottom;">  
                          <img alt="<spring:message code="required.authcode" />" onclick="this.src='captcha.jpg?'+Math.random()" width="93" height="30" src="captcha.jpg">  
                    </td>  
                        </tr>  
                        </table>  
                    </div>  
                    <div class="row check">  
                        <input id="warn" name="warn" value="true" tabindex="3" accesskey="<spring:message code="screen.welcome.label.warn.accesskey" />" type="checkbox" />  
                        <label for="warn"><spring:message code="screen.welcome.label.warn" /></label>  
                    </div> 

以上操作有些要修改源码,所以还是要把源码下载下来部署到Eclipse上修改比较方便,修改后编译成class文件放入到cas web里面

原文地址:https://www.cnblogs.com/cxyj/p/3884730.html