cas 4.1.5 添加驗證碼 親測成功

轉自 http://blog.csdn.net/attackmind/article/details/52052502 css

一、在cas工程的web.xml增長驗證碼功能的支持:html

<!-- 驗證碼功能 -->  
<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>

二、新建一個類UsernamePasswordCredentialWithAuthCode,該類繼承了java

org.jasig.cas.authentication.UsernamePasswordCredential,添加一個驗證碼字段,web

而且重寫equals和hashCode方法,添加關於驗證碼比較的信息spring

package org.spire.cas.core.authentication;  
  
import javax.validation.constraints.NotNull;  
import javax.validation.constraints.Size;  
  
import org.apache.commons.lang3.builder.HashCodeBuilder;  
import org.jasig.cas.authentication.UsernamePasswordCredential;  
  
public class UsernamePasswordCredentialWithAuthCode extends  
        UsernamePasswordCredential {  
    /** 
     * 帶驗證碼的登陸界面 
     */  
    private static final long serialVersionUID = 1L;  
    /** 驗證碼*/  
    @NotNull  
    @Size(min = 1, message = "required.authcode")  
    private String authcode;  
  
    /** 
     *  
     * @return 
     */  
    public final String getAuthcode() {  
        return authcode;  
    }  
  
    /** 
     *  
     * @param authcode 
     */  
    public final void setAuthcode(String authcode) {  
        this.authcode = authcode;  
    }  
  
    @Override  
    public boolean equals(final Object o) {  
        if (this == o) {  
            return true;  
        }  
        if (o == null || getClass() != o.getClass()) {  
            return false;  
        }  
  
        final UsernamePasswordCredentialWithAuthCode that = (UsernamePasswordCredentialWithAuthCode) o;  
  
        if (getPassword() != null ? !getPassword().equals(that.getPassword())  
                : that.getPassword() != null) {  
            return false;  
        }  
  
        if (getPassword() != null ? !getPassword().equals(that.getPassword())  
                : that.getPassword() != null) {  
            return false;  
        }  
        if (authcode != null ? !authcode.equals(that.authcode)  
                : that.authcode != null)  
            return false;  
  
        return true;  
    }  
  
    @Override  
    public int hashCode() {  
        return new HashCodeBuilder().append(getUsername())  
                .append(getPassword()).append(authcode).toHashCode();  
    }  
  
}

3.新建一個類AuthenticationViaFormActionWithAuthCode,該類繼承了org.jasig.cas.web.flow.AuthenticationViaFormAction類,增長一個驗證碼方法validatorCode:express

package org.spire.cas.core.authentication;  
  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpSession;  
  
import org.apache.commons.lang3.StringUtils;  
import org.jasig.cas.authentication.Credential;  
import org.jasig.cas.authentication.RootCasException;  
import org.jasig.cas.web.flow.AuthenticationViaFormAction;  
import org.jasig.cas.web.support.WebUtils;  
import org.springframework.binding.message.MessageBuilder;  
import org.springframework.binding.message.MessageContext;  
import org.springframework.webflow.execution.RequestContext;  
  
/** 
 * 驗證碼校驗類 
 *  
 * @author Langyou02 
 * 
 */  
public class AuthenticationViaFormActionWithAuthCode extends  
        AuthenticationViaFormAction {  
    /** 
     * authcode check 
     */  
    public final String validatorCode(final RequestContext context,  
            final Credential 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);  
  
        UsernamePasswordCredentialWithAuthCode upc = (UsernamePasswordCredentialWithAuthCode) credentials;  
        String submitAuthcode = upc.getAuthcode();  
        if (StringUtils.isEmpty(submitAuthcode)  
                || StringUtils.isEmpty(authcode)) {  
            populateErrorsInstance(new NullAuthcodeAuthenticationException(),  
                    messageContext);  
            return "error";  
        }  
        if (submitAuthcode.equals(authcode)) {  
            return "success";  
        }  
        populateErrorsInstance(new BadAuthcodeAuthenticationException(),  
                messageContext);  
        return "error";  
    }  
  
    private void populateErrorsInstance(final RootCasException e,  
            final MessageContext messageContext) {  
  
        try {  
            messageContext.addMessage(new MessageBuilder().error()  
                    .code(e.getCode()).defaultText(e.getCode()).build());  
        } catch (final Exception fe) {  
            logger.error(fe.getMessage(), fe);  
        }  
    }  
}

其中NullAuthcodeAuthenticationException和BadAuthcodeAuthenticationException是自定義的異常類,用於取得異常碼:apache

/* 
 * 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.spire.cas.core.authentication;  
  
import org.jasig.cas.authentication.RootCasException;  
  
/** 
 * The exception to throw when we know the authcode is null 
 *  
 * @author Scott Battaglia 
 * @version $Revision$ $Date$ 
 * @since 3.0 
 */  
public class NullAuthcodeAuthenticationException extends RootCasException {  
      
    /** 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.spire.cas.core.authentication;  
  
import org.jasig.cas.authentication.RootCasException;  
  
/** 
 * 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 RootCasException {  
      
    /** 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);  
    }}

四、在spire_cas工程的login_webflow.xml修改登陸驗證流程:服務器

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

並修改cas-servlet.xmlbean id ="AuthenticationViaFormAction"的class="org.spire.cas.core.authentication.AuthenticationViaFormActionWithAuthCode";session

五、增長國際化顯示信息:app

screen.welcome.label.authcode=\u9A8C\u8BC1\u7801:

screen.welcome.label.authcode.accesskey=a

required.authcode=\u5FC5\u987B\u5F55\u5165\u9A8C\u8BC1\u7801\u3002

error.authentication.authcode.bad=\u9A8C\u8BC1\u7801\u8F93\u5165\u6709\u8BEF\u3002

六、登陸頁面casLoginView.jsp添加驗證碼輸入框:

<section 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 style="vertical-align: bottom;">  
                    <img onclick="this.src='captcha.jpg?'+Math.random()" width="93" height="30" src="captcha.jpg">  
                                    </td>  
            </tr>  
        </table>  
       </section>

七、若是要默認中文頁面顯示,修改cas-servlet.xml 下的local Resolver默認值爲zh_CN:

 

 <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver" p:defaultLocale="zh_CN" />

八、效果圖(spire_cas是另一個web工程登陸跳轉到cas服務器認證):

九、參考博文:http://blog.csdn.net/zhu_tianwei/article/details/19153549

相關文章
相關標籤/搜索