爲CAS server添加Change Password和Forget Password功能

     最近一直在忙CAS相關的項目,team裏的兄弟已經配置好了CAS server,並作了一些編程和定製,添加了一個security code在登錄頁面,以及到ldap server/db驗證用戶的功能,但發現用初始密碼登錄後沒有強制修改密碼的功能,以及忘記密碼後,根據密碼問題自動重置密碼的功能也沒有。經過權衡,我覺得還是把Change/Forget password放到CAS中比較合理。於是着手改動CAS的source code。

     CAS我們採用的是3.3.3版的,其中用到了spring mvc2.5以及spring webflow1.0。理解spring mvc/webflow是這次改動的關鍵。粗粗來說,spring webflow的主要意思是用xml文件控制網頁的流向,頁面值傳遞靠一個Bean,比較單純的get/set值,由FormAction負責進行頁面值到這個bean的綁定,提交後的處理方法可以放在FormAction或者其他業務Bean中。

     下面就遇到的問題及解決方法簡單敘述一下:

     1. 添加Change Password的功能,等於是在普通驗證過程中插入一個分支流程,判斷如果是初始化密碼的話,就要進入強制修改密碼的流程,完成後返回主流程。這就決定了可以利用原有的FormAction以及Bean,添加相應的字段,和方法到Bean和FormAction中。

     這裏遇到一個問題,就是VO Bean的傳遞和使用,由於不熟悉spring webflow,看了很多例子,有的是使用ongl表達式在配置文件中,取出VO bean,然後再作爲方法參數傳遞給業務邏輯。

     這在一般的業務需求中是沒有問題的,但CAS的需求比較特殊,原有的流程是被暫停而不是執行結束,分支流程執行完之後,還要繼續執行原流程。這就意味着,原有主流程裏面用到的上下文參數和方法都需要繼續使用,如果跳轉到另外一個業務邏輯中的話,原有的上下文都無法取得。

     解決方法,在反覆查看了CAS所帶例子的AuthenticationFormAction之後,我發現,這個FormAction雖然用到CAS自己定義的centralAuthenticationService,但仍然是一個普通的FormAction,對於public final Event submit(final RequestContext context) throws Exception,也只是一個自己定義的方法,其父類FormAction裏面,並不含有此方法。這也就意味着,我也可以自己添加自己的方法,方法的參數就是RequestContext,這一點很重要,這解決了上述問題,從context裏面拿到VO bean,(這裏是credentials)處理後,繼續調用centralAuthenticationService,進行主流程。

 

     2. Forget Password是否和Change Password一樣,繼續利用原有的FormAction?

     這個問題很簡單,這是一個獨立的流程,和CAS中的logout等流程一樣,有自己的應用名稱,這裏我用了/password?作爲名稱。單獨寫好VO Bean以及FormAction,很快解決問題。(由於慣性,解決第一個問題後,還想繼續用原有的FormAction,結果弄來弄去很彆扭。)

 

     3. Validator的使用,按照說明,寫好一個Validator,然後配置到FormAction,當提交時調用BindAndValidate或者Validate,就會調用驗證方法。但如果像問題1,2那樣的話,一個流程有多個view,每次輸入應該有對應的驗證,問題是第一步輸入的驗證,肯定沒有第二步的內容,而如果延遲到最後一步再驗證,用戶還要倒回到前面的頁面重新輸入,這也不合理。只有是每一步都驗證一下,立刻返回結果才合理,這樣多個validate方法怎麼配置?

     在Validator中按需要寫入多個驗證方法,參數和標準的一致,(final Object o, final Errors errors),這裏的object其實就是VO bean。每一步調用時,明確其方法名,配置如下:<attribute name="validatorMethod" value="validateMyOwnMethod"/>。這裏CAS還有個特殊的地方,按照上述配置,在問題2中運行順利,但在問題1中一直報錯,nullpointexception。經過debug,發現每次要調用自己的validate方法時,validateMethodInvoker總是null。原來FormAction中的initialAction初始化這個變量,而在CAS中,initialAction被重寫了,但沒有調用其父類FormAction的initialAction,這樣纔會導致這個問題,補上super.initialAction(),問題解決。

發佈了38 篇原創文章 · 獲贊 1 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章