cas4.2.7學習(六)cas server 自定義登陸流程

cas 登陸和登出是基於spring web flow 的,如果不瞭解 spring web flow 是沒辦法修改的,所以在修改cas 的登陸時最好先了解一下 spring web flow。

下邊說一下簡單的修改:

1、先將target下的 webflow 文件夾拷貝到 WEB-INF下

2、登陸流程簡單的說明:

打開 其中login下的login-webflow.xml,並找到下邊的代碼:

<view-state id="viewLoginForm" view="casLoginView" model="credential">
        <binder>
            <binding property="username" required="true"/>
            <binding property="password" 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="realSubmit"/>
    </view-state>

看這段代碼的最後一句:<transition on="submit" bind="true" validate="true" to="realSubmit"/>,這句的大概意思就是當點擊submit按鈕之後,進入 realSubmit流程。這裏就是登陸驗證所以動作的開始!!

既然如此,我們在去找realSubmit:

<action-state id="realSubmit">
        <evaluate
                expression="authenticationViaFormAction.submit(flowRequestContext, flowScope.credential, messageContext)"/>
        <transition on="warn" to="warn"/>
        <!--
        To enable AUP workflows, replace the 'success' transition with the following:
        <transition on="success" to="acceptableUsagePolicyCheck" />
        -->
        <transition on="success" to="sendTicketGrantingTicket"/>
        <transition on="successWithWarnings" to="showMessages"/>
        <transition on="authenticationFailure" to="handleAuthenticationFailure"/>
        <transition on="error" to="initializeLogin"/>
    </action-state>

解釋一下這段代碼:

evaluate:可以理解爲realSubmit這個流程裏邊的核心處理代碼,authenticationViaFormAction:這個是具體處理的action,它是AuthenticationViaFormAction 類的註解,這個可以在源碼裏去找。最通俗話就是點擊頁面登陸之後,程序就進入AuthenticationViaFormAction 類的submit方法驗證登陸了。

下邊的transition 代表處理的不同結果,進入不同的下一個流程。如果驗證成功就進入sendTicketGrantingTicket。然後我們再去找sendTicketGrantingTicket,sendTicketGrantingTicket處理成功之後就進入

<decision-state id="serviceCheck">
        <if test="flowScope.service != null" then="generateServiceTicket" else="viewGenericLoginSuccess"/>
    </decision-state>

這裏有一個判斷,flowScope.service裏邊封裝的是客戶端請求的url,如果它不是是空的就進入  generateServiceTicket 否則進入viewGenericLoginSuccess,依次類推,整個步驟就是這樣了。

3、自定義流程:

默認的登陸流程是最基礎的,有兩種方式實現自定義流程,第一、我們可以在realSubmit之前添加一個或者多個自己寫的流程,第二直接修改realSubmit的evaluate讓登陸驗證指向我們自己寫的驗證代碼(這種方式需要參考源碼去寫,比如返回的key得跟transition 中on屬性一致等等)。

不管是哪種方式,我們都需要自己去寫局部或者整體的驗證代碼,步驟如下:

a、在根目錄下創建包org.jasig.cas,因爲cas註解掃描是從這個包開始的,這個可以在spring-configuration裏找到(項目裏沒有說明你沒有將其從target中拷貝上來,去target裏去找就行了),源碼是:

 <context:component-scan base-package="org.jasig.cas" />

這個不能改!!如果改成自己的包路徑,它就無法解析別的了。

b、創建自己的驗證action:

package org.jasig.cas.login;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jasig.cas.authentication.Credential;
import org.jasig.cas.web.support.WebUtils;
import org.springframework.binding.message.MessageContext;
import org.springframework.stereotype.Component;
import org.springframework.webflow.execution.RequestContext;

import com.demo.login.UsernamePasswordVCodeCredential;

@Component("authenticationViaFormVCodeAction")
public class AuthenticationViaFormVCodeAction {

	//添加自定義驗證方法1
    public final String validatorCode(RequestContext flowRequestContext,Credential credential,MessageContext messageContext) throws Exception {
		
    	System.out.println("進入了自定義驗證邏輯!!!!");
    	//這裏可以寫自己的驗證邏輯,比如驗證碼之類的。
    	return "success";
    	
        
    }
    
    
    //添加自定義驗證方法2
    public String goSys(RequestContext flowRequestContext,Credential credential,MessageContext messageContext) throws Exception {
		
    	HttpServletResponse response = WebUtils.getHttpServletResponse(flowRequestContext);
    	UsernamePasswordVCodeCredential ucredential = (UsernamePasswordVCodeCredential)credential;
    	//response.sendRedirect(ucredential.getSys_url());
    	return ucredential.getSys_url();
        
    }
    
}

c、添加或者修改流程

如果修改realSubmit,只需要修改一下evaluate指向,上邊已經說過。

如果在realSubmit之前添加一個新的流程:

在login-webflow.xml中添加一個action-state,讓它指向我們自己的驗證邏輯代碼,並設置transition ,如果成功進入realSubmit,失敗進入initializeLogin(重新初始化登陸頁)例如:

<!-- 自定義驗證 -->
<action-state id="vCodeValidate">
    <evaluate expression="authenticationViaFormVCodeAction.validatorCode(flowRequestContext, flowScope.credential, messageContext)" />
    <transition on="error" to="initializeLogin" />
    <transition on="success" to="realSubmit" />
</action-state>

然後將點擊登陸後的處理流程指向它:

<view-state id="viewLoginForm" view="casLoginView" model="credential">
        <binder>
            <binding property="username" required="true"/>
            <binding property="password" 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="vCodeValidate"/>
    </view-state>

以上就基本實現了自定義登陸了。

4、添加驗證參數

實際項目中可能要驗證的不止是用戶名和密碼,還需要有角色啊什麼的,這時就需要增加參數。

看上邊的代碼,很明顯<binding property="password" required="true"/>這個就是我們的參數了,所以我們要增加參數也需要在這裏配置,但是如果我們直接在這個後邊添加上新的參數,在後臺並沒有獲取到,原因是 默認的實體類配置的是:

<var name="credential" class="org.jasig.cas.authentication.UsernamePasswordCredential"/>

org.jasig.cas.authentication.UsernamePasswordCredential這個類裏邊只有用戶名和密碼,所以肯定是取不到的,所以我們要創建自己的實體類,並讓它繼承這個UsernamePasswordCredential,然後把新的屬性加進去就行了,例如:

package com.demo.login;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import org.jasig.cas.authentication.UsernamePasswordCredential;

public class UsernamePasswordVCodeCredential extends UsernamePasswordCredential{

	
	@NotNull
    @Size(
            min=1,
            message = "required.sys_url"
    )
    private String sys_url;

	public String getSys_url() {
		return sys_url;
	}

	public void setSys_url(String sys_url) {
		this.sys_url = sys_url;
	}

}

這樣就新加了一個 一個sys_url 參數進去,然後將配置原來的實體類代碼註釋掉,換成新的自定義實體類:

<!--默認的-->
<!-- <var name="credential" class="org.jasig.cas.authentication.UsernamePasswordCredential"/> -->
	<!--新的-->
	<var name="credential" class="com.demo.login.UsernamePasswordVCodeCredential"/>

再把新增的屬性添加都password後邊,例如:

 <binding property="password" required="true"/>
 <binding property="sys_url" required="true"/>
...

最後頁面上添加一個 name=sys_url的input即可,例如:

<input type="hidden" id="sys_url" name="sys_url" value="http://127.0.0.1:8081/prdicman" />

後臺獲取的時候只需要轉義一下:

UsernamePasswordVCodeCredential ucredential = (UsernamePasswordVCodeCredential)credential;

即可。

總結:

修改登陸流程,首先要了解spring web flow只要瞭解了spring web flow,那麼我們就可以隨意去修改了,這裏只需要注意的是將新的驗證代碼放到org.jasig.cas路徑下邊,讓Spring能裝載到就行了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章