集成基於CAS協議的單點登陸


  相信大家對單點登陸(SSO,Single Sign On)這個名詞並不感到陌生吧?簡單地說,單點登陸允許多個應用使用同一個登陸服務。一旦一個用戶登陸了一個支持單點登陸的應用,那么在進入其它使用同一單點登陸服務的應用時就不再需要重新登陸了。而CAS協議則正是各單點登陸產品所需要實現的協議,其全稱為Central Authentication Service。

  那為什么要寫這篇博客呢?這是因為在為公司的產品集成SSO的時候,我發現如果軟件開發人員不了解CAS協議,那么他在集成出現錯誤的時候將完全沒有辦法對出錯的原因進行分析。

 

單點登陸簡介

  如果您不知道單點登陸是什么,那么先來體會一次單點登陸。首先,請在一個全新瀏覽器(或者清除了登錄信息緩存的瀏覽器)的地址欄中鍵入www.hotmail.com,並進入您的hotmail郵箱。接下來,我們再訪問www.msn.com。請看網頁的右上角,您會發現您已經成功地通過剛剛的hotmail郵箱登入了www.msn.com

  這就是單點登錄:即使hotmail和msn的域名表明它們完完全全就是兩個不同的網站,但是由於它們使用了同一個單點登錄服務,因此在登陸hotmail之后再登陸msn,您剛剛輸入的用戶身份憑證依然有效。

  這種在一處登錄就能直接訪問其它應用的功能在企業級應用中是非常有用的。試想這樣一個情景:在每天的工作中,我們總需要通過瀏覽器訪問幾十個系統。如在瀏覽器中閱覽公司郵件,在需要撰寫Wiki的時候需要登錄到公司的Wiki系統。而報銷,請假,公司共享文件服務器等都需要用戶登陸。而且如果一個公司的IT部門對安全比較重視,那么他們還會要求員工在一定時間內更換一次密碼。試想一下,如果公司內部有幾十個系統,那么每個員工都需要維護幾十個密碼,並且每隔幾天就需要針對一個系統更改一個密碼。這種密碼管理的開銷無論對於員工本身還是對於IT開銷都是巨大的。

  反過來,如果這些系統都使用同一個用戶登錄服務,那么我們就可以免除在每次登入一個系統時都要輸入密碼的開銷,而且每個員工只需要管理一個密碼。

  因此,如果希望自己的企業級應用能夠成功地進入各個大型企業,那么這個產品就必須支持標准的單點登錄協議,即CAS協議。而只有在正確地理解了CAS協議的基礎之上,我們才能在我們的產品中正確地添加對單點登錄的支持。而這也便是我寫這篇文章的真正原因。

 

CAS協議的工作流程

  現在我們知道了單點登錄給我們所帶來的好處,但是我們並不知道它是如何工作的。由於CAS協議的執行流程較為復雜,因此,讓我們首先來看一個生活中的與單點登錄相似的事例,以輔助我們對單點登錄運行流程的理解。

  假設公司馬上就要來一位新同事,公司的行政人員需要在該同事到來前為他置辦好日常工作所需要的各種辦公用品。這些辦公用品包括工作用的電腦以及一套全新的辦公桌椅。在置辦完這些辦公用品后,該行政人員還要拿着購買辦公用品時所開具的發票去公司的財務部報銷。為了節省時間,該行政人員將會使用公司車輛在公司和賣場之間運送貨物。

  由於公司的司機常常在外奔波,因此他可能並不知道當天需要載着這位行政人員去購買辦公用品。在該行政人員找到他之后,他無法確認行政人員的用車安排是否與公司的其它安排相沖突。因此司機會讓行政人員打電話給公司的領導確認他是否可以用車。領導接到了該行政人員的電話並陳述用車的緣由后,行政人員會將電話轉交給司機,讓司機本人與領導溝通。在得到了領導的肯定答復后,司機就可以放心地載着該行政人員去電腦城購買電腦了。

  當該行政人員在當天再次找到該司機說需要購買辦公桌椅的時候,該司機就不再需要打電話詢問領導。因為他已經打電話和領導詢問過是否該行政人員需要用車的事情。

  在所有的辦公用品置辦完畢以后,該行政人員就會去公司的財務處報銷。在見到財務人員之后,該行政人員會直接說和領導之前已經溝通過並得到過批准。在該財務人員直接打電話給該領導並簡單提起購買辦公用品的事情后,領導就會很快地確認需要為一位新來的員工購買辦公用品的事情。在得到了肯定的答復后,該財務人員將直接接受報銷申請並迅速進入結算程序。

  在整個過程中,行政人員都是資源的訪問者及使用者。在每次嘗試使用這些資源時,資源的管理者都需要領導的批准來給與該行政人員使用資源的權利。只是在不同時刻,由於領導及資源管理者所得到的信息量並不相同,因此產生了三種不同的使用資源的流程。

  在第一次用車的時候,由於司機和領導都不清楚當天該行政人員需要用車,因此該行政人員需要從領導那里得到可以用車的許可,並將領導的許可轉交給司機,進而真正獲得使用公司車輛的權利。在該過程中,行政人員既需要與司機溝通,又需要與領導溝通,而司機也需要與領導溝通。

  在第二次用車的時候,由於司機已經知道領導對於車輛使用的授權,因此他不再需要額外的溝通而直接允許該行政人員使用公司車輛。在該過程中,行政人員只需要和司機溝通,而不再需要與領導打招呼。

  而在報銷的過程中,由於財務人員並不知道購買辦公用品是否已經獲得了領導的同意,因此需要詢問領導。而此時領導已經知道財務人員是為了新入職的同事准備的辦公用品,因此將直接同意對該筆款項進行報銷,也不再需要行政人員再次向領導解釋公司將來一名新員工的事宜。在該過程中,財務人員需要與行政人員以及領導溝通。

  CAS協議的運行流程實際上與上面所舉示例的運行基本一致:第一次訪問一個應用時,系統將要求用戶轉到SSO系統,輸入表示自己身份憑證的用戶名和密碼,才能得到訪問該應用的權限。而在第二次訪問同一應用的時候,由於應用已經知道該用戶曾經獲得了訪問權限,因此將直接允許用戶對該應用進行訪問。如果用戶訪問另一個應用,那么該應用將會根據用戶當前所得到的身份憑證去SSO系統認證,從而得知用戶已經擁有了對該應用的訪問權限。

  下面就是通過CAS協議第一次訪問應用並成功登錄的流程圖:

  上面的流程圖列出了用戶在第一次登錄應用時所需要經歷的步驟。首先,用戶通過在瀏覽器的地址欄中鍵入https://app.ambergarden.com來嘗試訪問應用。由於此時應用會話並沒有被創建,因此應用將拒絕用戶的登錄請求,並通過302響應將用戶重定向到https://sso.ambergarden.com以要求用戶首先通過SSO進行登錄。注意在該重定向所標明的地址中包含了一個額外的URL參數service。其標示了用戶原本想要訪問的應用所在的位置。在瀏覽器接收到了302響應后,其將自動跳轉到SSO。由於SSO中也沒有與瀏覽器建立相應的會話,因此其將返回給用戶一個登錄界面,要求用戶通過輸入用戶名和密碼完成登錄。在用戶輸入了用戶名/密碼並點擊登錄按鈕后,頁面邏輯將發送一個POST請求到SSO中以建立會話。如果用戶登錄成功,那么SSO將返回一個302重定向響應,並且該重定向響應中由Location所標明的地址還帶了一個額外的參數ticket。在瀏覽器接收到該重定向響應之后,其將向重定向地址發送一個GET請求,並且該請求中還包含了剛剛從SSO所返回的ticket參數。在應用接受到該請求后,其將使用ticket參數所標明的憑據向SSO發送請求以驗證該憑據的合法性。如果驗證成功,那么應用將會認為當前對應用的訪問是一個已經得到SSO認證的合法用戶發起的,進而為該用戶創建會話。

  在瀏覽器再次訪問該應用的時候,由於應用已經為當前瀏覽器創建了相應的會話,因此應用將能識別出它是一個合法的經過SSO驗證的用戶:

  相較於對應用的第一次訪問而言,第二次訪問的流程圖實際上就非常容易理解了。實際上,這就是在已經建立了會話之后再次訪問應用時的流程圖。

  而在訪問其它應用時,CAS協議運行的流程圖將如下所示:

  如果您已經理解了首次登錄流程,那么該流程就非常容易理解了。首先,用戶嘗試訪問處於https://app2.ambergarden.com下的應用。由於之前用戶並沒有登錄過該應用,因此該應用發送一個302請求來將用戶重定向到SSO服務。而這里的URL參數service與首次登錄時候的意義一樣,用來在這一系列通信中記錄登錄成功后所需要返回到的服務地址。

  瀏覽器一旦接收到了302響應,那么其將立刻執行重定向並訪問SSO服務。由於用戶在之前訪問第一個應用的時候已經建立了SSO會話,因此SSO服務將立即返回一個302響應,並在響應的Location中使用URL參數ticket標示用戶從SSO所得到的憑據。在接到302響應后,瀏覽器再次重定向,並訪問應用。應用同樣使用ticket所標示的憑據向SSO請求驗證。在驗證成功后,應用將會認為當前訪問用戶是合法的,因此將為該用戶創建會話。在該過程中,用戶沒有輸入任何信息,而只經過了幾次瀏覽器跳轉就驗證了用戶的合法性。

 

CAS協議集成

  好了,在了解了基於CAS協議的SSO是如何工作的之后,我們就可以開始考慮如何在應用中集成對CAS協議的支持了。

  我們所要做的第一步就是分析上面所講的各個流程中的每一步對CAS協議所定義的各接口,進行使用的方式。在分析的過程中,我們需要時刻提醒自己是在為我們的應用添加CAS協議支持,而不是實現一個基於CAS協議的SSO。這會導致我們在查看CAS協議時的角度與實現一個基於CAS協議的SSO有以下幾點不同:

  1. 不必要理解CAS協議中的所有接口以及各接口中的所有參數。CAS協議中列出的很多接口實際上都是用來在瀏覽器和SSO服務之間進行交互的。因此我們不必要非常仔細地察看這些接口,而只需要知道這些接口所執行的功能以及產生的數據即可。而且即使是我們會用到的接口中也會有一部分參數並不會被用到。我們只需要關注在我們的應用使用SSO流程中所可能涉及到的各個參數即可。
  2. 需要注意在流程中瀏覽器與應用之間的交互。在前面所展示的各個流程圖中已經能夠看到,應用是通過一系列302重定向響應等HTTP標准方法來完成將用戶重定向到SSO服務這一動作的。

  那么我們回過頭來回憶一下用戶首次登陸成功的流程圖:

  在該流程圖里面,我們需要關心的就是到底誰與應用產生了交互,以及在交互過程中使用了什么樣的接口及參數。可以看到,在用戶通過瀏覽器第一次訪問應用的時候,應用需要返回給用戶一個302響應,而響應中所指定的地址就是SSO所提供的登陸接口。因此我們要做得第一步就是要理解Login這個URL所做的工作。

  從API文檔中可以看到,Login這個URL可以提供兩種服務:請求用戶輸入身份憑證(Credential Requester)以及驗證用戶的身份憑證(Credential Acceptor)。在這張流程圖里面,我們兩次向該URL發送請求。第一次請求所使用的是該URL的第一種服務,該服務將請求用戶輸入用戶的身份憑證,如顯示一個登陸頁面。而在用戶輸入了用戶名和密碼后,向該URL發送的請求就將使用第二種服務。在這兩次請求中,URL中的service參數用來標明用戶成功登陸后從SSO重定向出來時所需要跳轉到的地址。由於我們是在為自己的應用添加SSO支持,那么該服務自然需要指向我們的應用。

  OK,現在我們就可以開始第一步集成了。該步驟的工作就是:當一個用戶訪問應用的時候,如果應用中沒有該用戶所對應的會話,那么返回302響應,並在響應中標示跳轉的地址為SSO所在的地址,並在service參數中標明我們的應用所在的地址。如果這一切功能都正確地實現,那么對應用的訪問會自動跳轉到SSO服務,並在成功登陸后再次請求訪問我們自己的應用。此時的訪問會傳入一個URL參數ticket以表示從SSO處得到的憑證。

  如果正確地完成了第一步的集成,那么我們就可以開始集成的第二個步驟了,那就是向SSO服務驗證用戶。在第一步中,SSO最終驗證了用戶的身份並向瀏覽器中返回了一個302響應。瀏覽器接收到該302響應后,其便向302響應所標示的地址進行跳轉。在應用接受到了包含ticket參數的請求后,它需要使用該ticket參數所記錄的信息來訪問serviceValidate接口,以驗證所傳入的ticket參數是否是一個真正的從SSO所返回的憑據。一旦驗證成功,那么該用戶就是一個合法用戶。此時應用就需要為該用戶創建一個會話並將他重定向到程序的初始頁面,如應用的Dashboard等。

  而在用戶再次訪問應用的時候,由於應用中已經包含了該用戶所對應的會話,因此其不會再與SSO產生交互,因此也不再需要為SSO集成做任何工作。同樣的,由於第三個流程也使用了同樣的接口,因此我們也不再需要做任何額外的工作。

  就這樣,僅僅通過這兩步,我們就可以完成對SSO登陸功能的集成了。是不是很簡單?

  除此之外,我們還可以選擇支持Single Logout(有些討論里面叫Single Sign Off)。但是反對該功能的人也不少。其中的原因就因為用戶常常認為點擊Logout按鈕是從當前應用中安全地退出,但是這實際上導致用戶所登陸的所有使用該SSO服務的應用都將退出。因此在決定對該功能進行支持之前一定要考慮清楚該功能是否會真的為用戶帶來好處。

 

需要注意的問題

  就像大家在上面所看到的一樣,在應用中集成對SSO的支持實際上並不需要多少工作。甚至可以說,一個有相關經驗的人可以在幾個小時內就能完成。但是反過來說,如果在集成中沒有注意到一些問題,那么這些問題可能會耽誤您幾天的時間。因此在本節中,我會簡單地說一下我在SSO集成中的一些經驗。

  首先就是CAS協議的API文檔的閱讀方法。我一直認為,對於這種側重於流程的協議,協議的運行流程以及在該流程中的數據流是關鍵。因此一上來就沖到API文檔中並嘗試理解每個接口的含義,輸入及輸出並不是一個好的辦法。可能對於外國人而言,先了解接口再弄懂運行流程是一種比較簡單的方式,但是似乎這種方式並不太適合中國人的思維。這也就是我為什么一上來就講解SSO的運行流程的原因。

  而在CAS協議的API文檔中,對ticket進行驗證的接口有好幾套,如第一版中的/validate接口在第二版中演進為/servicevalidate和/proxyvalidate兩個接口等。請根據需要選擇相應的一套接口即可。

  一個需要注意的地方就是,很多SSO里面都有一個Filter,用來標示允許使用該SSO服務的各個應用。該Filter會阻止非法應用從SSO服務登陸。否則該非法應用將可以嘗試對SSO展開攻擊。舉一個最簡單的DDOS攻擊的例子。在我的一篇博客里已經介紹過對用戶名/密碼對的驗證實際上是一個較為耗時的行為,因此該步是SSO服務中最為脆弱的地方。如果一個惡意人員盯上了該SSO服務,並在一個用戶群基數較大的網站上找到了漏洞,更改了它的SSO服務配置,那么該網站的用戶就會在登陸該網站的時候跳轉到該SSO服務。接下來這些用戶就會嘗試用他們的用戶名/密碼對在該SSO服務上登陸,從而在這些用戶的幫助下展開了DDOS攻擊。因此在通常情況下,SSO服務都會配置一個白名單。而在進行SSO集成之前,我們則首先需要向該白名單中添加我們的應用。

  還有一個比較容易被忽略的問題就是會話的時效性問題。在整個SSO的使用中存在着兩種會話:用戶在應用程序中的會話以及用戶在SSO服務上的會話。在一般情況下,SSO服務上的會話持續時間都會比應用程序中的會話時間略長。這樣在應用程序的會話過期時,用戶可以直接通過刷新頁面等方式從SSO服務重新建立會話。但是在進行集成時,為了調試方便,我們常常會將應用會話時間調整得很長,甚至長於SSO服務上的會話時間,從而沒有測試應用程序會話過期進而通過SSO會話來刷新應用程序會話的情況。

 

Reference

CAS協議:http://jasig.github.io/cas/development/protocol/CAS-Protocol-Specification.html

 

轉載請注明原文地址並標明轉載:http://www.cnblogs.com/loveis715/p/4491417.html

商業轉載請事先與我聯系:silverfox715@sina.com


免責聲明!

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



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