單點登陸CAS使用記(四):爲登陸頁面加上驗證碼

CAS默認的登陸頁面樣式以下,只有用戶名與密碼兩項驗證項目。css

如今須要爲首頁登陸加上驗證碼功能。html

第一步:首頁對默認登陸頁面的樣式進行了調整,使其看上去還算美觀。java

在頁面上加上了驗證碼項目。web

 

第二步:導入驗證碼生成工具包及生成驗證碼配置express

pom.xml中加入以下配置服務器

<dependency>
    <groupId>com.google.code.kaptcha</groupId>
    <artifactId>kaptcha</artifactId>
    <version>2.3.2</version>
</dependency>

 

web.xml中加入以下配置(只配置了寬高度等其餘默認)session

    <servlet>
        <servlet-name>captchacode</servlet-name>
        <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
        <init-param>
            <description>邊框粗細度。必須是一個大於0的值</description>
            <param-name>kaptcha.border.thickness</param-name>
            <param-value>1</param-value>
        </init-param>
        <init-param>
            <description>圖片的寬度</description>
            <param-name>kaptcha.image.width</param-name>
            <param-value>140</param-value>
        </init-param>
        <init-param>
            <description>圖片的高度</description>
            <param-name>kaptcha.image.height</param-name>
            <param-value>55</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>captchacode</servlet-name>
        <url-pattern>/captchacode</url-pattern>
    </servlet-mapping>

 

登陸頁jsp中app

<form:input cssClass="required" cssErrorClass="error" id="imgverifycode" path="imgverifycode" htmlEscape="true" autocomplete="off" placeholder="輸入驗證碼" />
<img id="cimg" src="${base_path}/captchacode" onclick="refreshcaptchacode(this)" title="看不清?點擊更換另外一個。"/>

 JavaScript:jsp

function refreshcaptchacode(obj) {
    obj.setAttribute("src", base_path+ "/captchacode?date=" + new Date());
}

 

第三步:CAS源碼須要作哪些修改?maven

1.首先將新增項目imgverifycode綁定到表單

打開login-webflow.xml,找到這一段

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

 

修改成(注意紅色加大部分):

    <view-state id="viewLoginForm" view="casLoginView" model="credentials">
        <binder>
            <binding property="username" />
            <binding property="password" />
            <binding property="imgverifycode" />
        </binder>
        <on-entry>
            <set name="viewScope.commandName" value="'credentials'" />
        </on-entry>
        <transition on="submit" bind="true" validate="true" to="imgverifycodeValidate">
            <evaluate expression="authenticationViaFormAction.doBind(flowRequestContext, flowScope.credentials)" />
        </transition>
    </view-state>

    <!-- 並增長了下面這一段代碼 -->
    <action-state id="imgverifycodeValidate">
        <evaluate
            expression="authenticationViaFormAction.validatorCode(flowRequestContext, flowScope.credentials, messageContext)" />
        <transition on="error" to="generateLoginTicket" />
        <transition on="success" to="realSubmit" />
    </action-state>

 

主要是在登陸的工做流中加上了 驗證碼提交綁定以及驗證碼驗證處理。

其次,在UsernamePasswordCredentials.java中添加驗證碼字段。

    /** The imgverifycode. */
    @NotNull
    @Size(min = 1, message = "required.imgverifycode")
    private String imgverifycode;

對於的修改一下equals,hascode方法。

    @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 (username != null ? !username.equals(that.username)
                : that.username != null)
            return false;
        if (password != null ? !password.equals(that.password)
                : that.password != null)
            return false;
        if (imgverifycode != null ? !imgverifycode.equals(that.imgverifycode)
                : that.imgverifycode != 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
                + (imgverifycode != null ? imgverifycode.hashCode() : 0);
        return result;
    }
View Code

 

2.添加驗證邏輯

注意上一段配置加上了一個action-state:imgverifycodeValidate,執行的是AuthenticationViaFormAction.validatorCode(...)方法

打開AuthenticationViaFormAction.java(cas-server-core工程下),添加以下方法

    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();
        
        UsernamePasswordCredentials upc = (UsernamePasswordCredentials) credentials;
        String submitAuthcode = upc.getImgverifycode();
        
        if (!StringUtils.hasText(submitAuthcode))
        {
            populateErrorsInstance(new NullImgVerifyCodeAuthenticationException(),
                    messageContext);
            return "error";
        }
        
        if (StringUtils.equalsIgnoreCase((String) session.getAttribute(Constants.KAPTCHA_SESSION_KEY), captchacode))
        {
            return "success";
        }
        populateErrorsInstance(new BadImgVerifyCodeAuthenticationException(),
                messageContext);
        return "error";
    }

 

其中NullImgVerifyCodeAuthenticationException,BadImgVerifyCodeAuthenticationException是仿照源碼異常類新增的自定義異常類。

NullImgVerifyCodeAuthenticationException.java

/*
 * Copyright 2007 The JA-SIG Collaborative. All rights reserved. See license
 * distributed with this file and available online at
 * http://www.ja-sig.org/products/cas/overview/license/
 */
package com.tongxiang.cas.auth.handler;

import org.jasig.cas.ticket.TicketException;

/**
 * Generic Bad Credentials Exception. This can be thrown when the system knows
 * the credentials are not valid specificially because they are bad. Subclasses
 * can be specific to a certain type of Credentials
 * (BadUsernamePassowrdCredentials).
 * 
 * @author Scott Battaglia
 * @version $Revision$ $Date$
 * @since 3.0
 */
public class NullImgVerifyCodeAuthenticationException extends TicketException
{
    
    /**
     * Static instance of class to prevent cost incurred by creating new
     * instance.
     */
    public static final NullImgVerifyCodeAuthenticationException ERROR = new NullImgVerifyCodeAuthenticationException();
    
    /** UID for serializable objects. */
    private static final long serialVersionUID = 3256719585087797044L;
    
    /**
     * Default constructor that does not allow the chaining of exceptions and
     * uses the default code as the error code for this exception.
     */
    private static final String CODE = "required.imgverifycode";
    
    /**
     * Default constructor that does not allow the chaining of exceptions and
     * uses the default code as the error code for this exception.
     */
    public NullImgVerifyCodeAuthenticationException()
    {
        super(CODE);
    }
    
    /**
     * Constructor to allow for the chaining of exceptions. Constructor defaults
     * to default code.
     * 
     * @param throwable the chainable exception.
     */
    public NullImgVerifyCodeAuthenticationException(final Throwable throwable)
    {
        super(CODE, throwable);
    }
    
    /**
     * Constructor method to allow for providing a custom code to associate with
     * this exception.
     * 
     * @param code the code to use.
     */
    public NullImgVerifyCodeAuthenticationException(final String code)
    {
        super(code);
    }
    
    /**
     * Constructor to allow for the chaining of exceptions and use of a
     * non-default code.
     * 
     * @param code the user-specified code.
     * @param throwable the chainable exception.
     */
    public NullImgVerifyCodeAuthenticationException(final String code,
            final Throwable throwable)
    {
        super(code, throwable);
    }
}
View Code

BadImgVerifyCodeAuthenticationException.java

/*
 * Copyright 2007 The JA-SIG Collaborative. All rights reserved. See license
 * distributed with this file and available online at
 * http://www.ja-sig.org/products/cas/overview/license/
 */
package com.tongxiang.cas.auth.handler;

import org.jasig.cas.ticket.TicketException;

/**
 * Generic Bad Credentials Exception. This can be thrown when the system knows
 * the credentials are not valid specificially because they are bad. Subclasses
 * can be specific to a certain type of Credentials
 * (BadUsernamePassowrdCredentials).
 * 
 * @author Scott Battaglia
 * @version $Revision$ $Date$
 * @since 3.0
 */
public class BadImgVerifyCodeAuthenticationException extends TicketException
{
    
    /**
     * Static instance of class to prevent cost incurred by creating new
     * instance.
     */
    public static final BadImgVerifyCodeAuthenticationException ERROR = new BadImgVerifyCodeAuthenticationException();
    
    /** UID for serializable objects. */
    private static final long serialVersionUID = 3256719585087797044L;
    
    /**
     * Default constructor that does not allow the chaining of exceptions and
     * uses the default code as the error code for this exception.
     */
    private static final String CODE = "error.authentication.imgverifycode.bad";
    
    /**
     * Default constructor that does not allow the chaining of exceptions and
     * uses the default code as the error code for this exception.
     */
    public BadImgVerifyCodeAuthenticationException()
    {
        super(CODE);
    }
    
    /**
     * Constructor to allow for the chaining of exceptions. Constructor defaults
     * to default code.
     * 
     * @param throwable the chainable exception.
     */
    public BadImgVerifyCodeAuthenticationException(final Throwable throwable)
    {
        super(CODE, throwable);
    }
    
    /**
     * Constructor method to allow for providing a custom code to associate with
     * this exception.
     * 
     * @param code the code to use.
     */
    public BadImgVerifyCodeAuthenticationException(final String code)
    {
        super(code);
    }
    
    /**
     * Constructor to allow for the chaining of exceptions and use of a
     * non-default code.
     * 
     * @param code the user-specified code.
     * @param throwable the chainable exception.
     */
    public BadImgVerifyCodeAuthenticationException(final String code,
            final Throwable throwable)
    {
        super(code, throwable);
    }
}
View Code

而且,在messages_zh_CN.properties文件中添加對應上面兩個異常類的兩個異常消息

required.imgverifycode=請輸入驗證碼
error.authentication.imgverifycode.bad=驗證碼錯誤

 

 3.驗證

 

 

OK。

 

 

 


單點登陸CAS使用記系列:

相關文章
相關標籤/搜索