【SSO單點系列】(3):CAS4.0 登錄頁驗證碼的添加


2016.08.23 更新

注意:這個教程只適合4.0版本的,4.1以及以上的版本的已經不試用了, 后面幾篇有人提到過

 

源碼網盤鏈接更新了下 : 鏈接: http://pan.baidu.com/s/1ntJ7KvR 密碼: svhb

2015.8.14更新

有園子 說看不到驗證碼的錯誤提示,請參考40樓回復進行修改

附上:

解決方案:
1.把版本升到最新的 v4.0.4
2.然后需要把CnBlogAuthenticationViaFormAction 類中
new MessageBuilder().code(“xxx”).build();
return "error"
改成
new MessageBuilder().error().code(“xxx”).build();
returnnewEvent(ERROR);
依次改就ok了

---------------------

 

這一篇主要是講解怎么在登錄頁上添加驗證碼功能,默認的登錄頁是只有用戶名與密碼功能。其他我覺得加驗證碼沒什么用,因為現在我部門做的系統主要是放在內網里,外網是不能訪問的。登錄頁的驗證碼主要是為了防止進賬號進行暴力破解,不過我覺得客戶估計也不會沒事去搞這玩意。以上只是我自己的個人見解,可能有失偏頗,就當作是對客戶的憤怒的一種發泄吧,大家看看就好,最近真是被客戶搞得頭都大了。不過,如果你的系統放在外網上,那驗證碼是必須要加上的 。  好了,牢騷發的差不多了,下面進入正題吧!

 

最終效果圖

簡單做了個頁面,一般情況的話都會有美工設計好界面,然后大家進行開發就行了。驗證碼插件 用的是 kaptcha ,具體用法網上很多,大家google一下就搜到了,用起來蠻簡單的。

 

開發

現在開始講解怎么在單點流程中添加驗證碼驗證碼的操作!

 

工程導入

在第一篇 環境的架設中,我們都是直接在tomcat下面操作的,現在我們需要把cas server 導入到我們的eclipse中,才能繼續進行操作。

找到我們下載的 cas-server-4.0.0-release.zip  解壓,進入子目錄找到 cas-server-webapp 工程,因為代碼使用maven搭建的,所有導入時選擇maven導入。導入完成后,大致的結構如下:

ps:需要注意的是,大家要把第二篇里面修改的內容添加到你導入的工程里,不然會沒效果的,大家一定注意。

 

 

 

配置修改

1.打開 login-webflow.xml 文件,大家可能會覺得有點熟悉 。對的,cas有使用Spring Web Flow框架。 找到下面代碼:

 

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

 

大家看到沒,這邊有一個form (viewLoginForm),里面有username、password兩個屬性,沒錯,這就是對應我們登錄頁面上的表單。所以我們要在這邊加上驗證碼這個屬性。

 

        <binder>
            <binding property="username" />
            <binding property="password" />
             <!-- 新添加 -->
            <binding property="captcha" />
        </binder>    

 

 

 

2.我們只在這邊添加一個屬性后,夠嗎?當然不夠,因為這個配置實際上有在代碼中對應一個java類 UsernamePasswordCredential.java,具體路徑為 org.jasig.cas.authentication.UsernamePasswordCredential.java ,查看源碼看看,實際上就是一個javabean而已。那么我們就可以繼承它,然后加上我們的captcha 屬性!完成后的代碼如下:

 

public class UsernamePasswordCaptchaCredential extends
        UsernamePasswordCredential {

    /**
     * 
     */
    private static final long serialVersionUID = -864735145551932618L;
    @NotNull
    @Size(min=1,message = "required.captcha")
    private String captcha;
    
    //省略set、get方法
}

 

 

 

 

3.好了,新的javabean誕生了。夠了嗎?實際還有一個地方要修改,回到 login-webflow.xml 文件,第27行左右,修改如下:

   <!-- 修改后前 -->
    <var name="credential" class="org.jasig.cas.authentication.UsernamePasswordCredential" />
    
    <!-- 修改后 -->
   <!--  <var name="credential" class="org.jasig.cas.authentication.UsernamePasswordCredential" /> -->
    
    <var name="credential" class="org.jasig.cas.authentication.UsernamePasswordCaptchaCredential" />

 

如果大家包名、類名都和原來一樣,那么這步可以跳過。

ps:4.0以前的類是  org.jasig.cas.authentication.principal.UsernamePasswordCredentials.java ,4.0以后有變化,大家要注意。

 

4.好了,接下來要添加校驗驗證碼的流程了,還是剛才viewLoginForm 那里,我們把它修改成下面:

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

--------------------------------我是分割線----------------------------- <!-- 修改后 --> <view-state id="viewLoginForm" view="casLoginView" model="credential"> <binder> <binding property="username" /> <binding property="password" /> <binding property="captcha" /> </binder> <on-entry> <set name="viewScope.commandName" value="'credential'" /> </on-entry> <transition on="submit" bind="true" validate="true" to="validatorCaptcha"> <evaluate expression="authenticationViaFormAction.doBind(flowRequestContext, flowScope.credential)" /> </transition> </view-state> <!-- 添加一個 validatorCaptcha 校驗驗證碼的操作 --> <action-state id="validatorCaptcha"> <evaluate expression="authenticationViaFormAction.validatorCaptcha(flowRequestContext, flowScope.credential, messageContext)"></evaluate> <transition on="error" to="generateLoginTicket" /> <transition on="success" to="realSubmit" /> </action-state>

 

我們在配置中添加了一個 validatorCaptcha 的操作,同時可以看到 expressionauthenticationViaFormAction.validatorCaptcha(...)

所以我們需要在  authenticationViaFormAction 中添加一個校驗驗證碼的方法 validatorCaptcha()。

authenticationViaFormAction 這個bean是配置在 cas-servlet.xml 中的:

 

  <bean id="authenticationViaFormAction" class="org.jasig.cas.web.flow.AuthenticationViaFormAction"
        p:centralAuthenticationService-ref="centralAuthenticationService"
        p:warnCookieGenerator-ref="warnCookieGenerator"
        p:ticketRegistry-ref="ticketRegistry"/>

 

 

 

我們可以看看 org.jasig.cas.web.flow.AuthenticationViaFormAction 的源代碼,里面有一個 submit 方法,這個就是我們提交表單時的方法了。

我們也重寫下吧,大概修改成下面的:

public class CnBlogAuthenticationViaFormAction extends AuthenticationViaFormAction{

    public final String validatorCaptcha(final RequestContext context, final Credential credential,
            final MessageContext messageContext){
        
            final HttpServletRequest request = WebUtils.getHttpServletRequest(context);  
            HttpSession session = request.getSession();  
            String captcha = (String)session.getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);  
            session.removeAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);  
            
            UsernamePasswordCaptchaCredential upc = (UsernamePasswordCaptchaCredential)credential;  
            String submitAuthcodeCaptcha =upc.getCaptcha(); 
            
            
            if(!StringUtils.hasText(submitAuthcodeCaptcha) || !StringUtils.hasText(submitAuthcodeCaptcha)){
                messageContext.addMessage(new MessageBuilder().code("required.captcha").build()); 
                return "error";    
            }  
            if(submitAuthcodeCaptcha.equals(captcha)){    
                return "success";  
            }  
            messageContext.addMessage(new MessageBuilder().code("error.authentication.captcha.bad").build());
            return "error";    
    }
}

 

這邊有拋出兩個異常,這兩個異常信息 required.captchaerror.authentication.captcha.bad 需要在 messages_zh_CN.properties 文件下添加

required.captcha=必須輸入驗證碼。
error.authentication.captcha.bad=您輸入的驗證碼有誤。

 

然后把 authenticationViaFormAction 這個Bean路徑修改為我們新添加的鏈接,這個就不貼了,大家照上面改就行了

修改over!

 

總結

這樣,添加驗證碼的操作基本就完成了,大家可以嘗試看看 。效果圖,已經貼在帖子的最前面了。

 

一個人的我,只能在這 邊寫博客邊祝福大家 平安夜 ,多吃蘋果,平平安安。

。。。
打完收工


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM