基本概念
SSO(Single Sign On)單點登錄,是在多個應用系統中,用戶只需要登錄一次就能訪問所有相互信任的應用系統。它包括將這次的主要登錄映射到其他應用中用戶同一個用戶的登錄機制。
SSO可以分為Web SSO和桌面SSO,Web SSO體現在客戶端,桌面SSO則是操作系統級別的SSO(如登錄了Windows就可以使用QQ)。
現在我們所講的SSO,通常是Web SSO,也就是SSO應用間走Web協議(HTTP/SSL),並且多個應用共享一個SSO入口。
原理介紹
系統角色
User
User可以有多個,User訪問Web應用並被SSO認證中心鑒權和授權。
Web應用
Web應用可以有多個,並且受SSO認證中心的保護,是User訪問的目標。
SSO認證中心
僅包含一個,用戶未授權的訪問請求會被重定向到SSO認證中心。
CAS
CAS是耶魯(Yale)大學發起的一個開源項目,在Java Web SSO中,CAS占據了大約八成的份額,簡單時效且足夠安全。
CAS的體系結構
CAS Server
CAS Server完成對用戶的認證工作,CAS Server需要獨立部署,有不止一種CAS Server實現。Yale CAS Server和ESUP CAS Server都是不錯的選擇。
CAS Server 會處理用戶名/密碼等憑證,並可能從數據庫或其他來源檢索用戶名和密碼,對於這種方式,CAS提供靈活的接口/實現分離方式,意味着CAS Server可以支持任何的認證方式,並且與CAS協議分離。
CAS Client
CAS Client負責部署在客戶端(Web應用側)。當有對本地受保護的Web資源的訪問請求,並且需要對請求方進行身份驗證,Web應用不再接受任何用戶名/密碼等類似的Credentials,而是重定向到CAS Server進行認證。
目前CAS Client支持非常多的客戶端(Java/PHP/.Net)等。
CAS協議
CAS協議有從v1到v3的版本,在v2版本中開始支持了XML,在v3版本中支持了AOP,因此對於使用Spring開發的項目來說是非常友好的。
CAS協議的基礎思想都是基於Kerberos的票據方式。
基礎協議

圖1 基礎模式
- CAS Client以Filter的形式保護Web應用的受保護資源,過濾從客戶端過來的每一個請求(Step 1)。
- CAS Client分析HTTP請求中是否包含Service Ticket,如果沒有則重定向到CAS Server(Step 2)。
- 用戶認證過程,如果用戶提供了正確的Credentials,CAS Server會產生隨機的Ticket,然后緩存該Ticket(Step3),並生成TGC(Ticket Grant Cookie)給User瀏覽器。
- 並重定向用戶到CAS Client並攜帶剛才產生的Ticket(Step4)。
- CAS Client與CAS Server通過Ticket完成身份認真(Step4和Step5)。
- 驗證成功后,CAS Client對當前Request用戶進行服務。
- 用戶再次訪問時攜帶TGC,CAS Server會判斷該Cookie的有效性並決定是否再次驗證。
CAS代理模式
基礎協議已經能夠滿足絕大多數的場景,但是對於通過service1訪問service2這種場景就無能為力了,如果我們對service2也進行驗證,從用戶角度來說,將會看到頻繁的重定向,因此引入了Proxy(代理)模式,由CAS Client代理用戶去訪問其他Web應用。
代理的前提是需要CAS Client擁有身份信息(類似憑據),用戶持有的TGC(Ticket Granted Cookie),而代理持有的是PGT(Proxy Granted Ticket),憑借TGC用戶可以免登陸獲取其他應用的Service Ticket,同樣的,通過PGT,Web應用可以代理用戶實現后端認真而無需前端的用戶參與。
如何獲取PGT?
如下圖示,CAS Client在基礎協議之上,提供了一個額外的PGT URL給CAS Server,CAS Server通過該接口提供PGT給CAS Client。

圖2 Proxy模式
與基礎協議不同,在Proxy模式中起作用的是PT(Proxy Ticket),基礎模式使用的是ST(Service Ticket)。

圖3 代理模式的訪問模式
當helloservice需要helloservice2的數據時,helloservice首先使用自己保存的PGT向CAS Server獲取PT。
當獲取到PT之后,helloservice攜帶該PT向helloservice2請求數據。
Helloservice2使用該PT向CAS Server驗證請求,CAS Server返回驗證結果。
Helloservice2此時知道可以合法的為Helloservice服務,從而返回數據。
業界方案
JA-SIG CAS
開源SSO實現中最為成熟的一個,良好的安全性和易用性。
而且CAS客戶端有Java,.Net,以及PHP版本,良好支持了現有產品,SSO將會基於CAS進行開發。
JOSSO
較早的一個實現,但與技術綁定過深,缺乏良好的適用性和文檔。
CoSign
類似於CAS的一個實現,CAS Server基於GCI,在C/C++項目中使用較多。
WebAuth
非常早期的SSO方案,使用Perl編寫,對Java的支持性很差。
OpenSSO
被甲骨文收購,不再提供支持
CAS安全性
CAS的安全性是非常重要的,從CAS V1到V3,其都依賴與SSL,它假定了用戶在一個非常不安全的環境中使用SSO,HTTP傳送的密碼和Ticket票據都是不安全的。
TGC/PGT的安全性
對於一個CAS用戶來說,最重要的事情是保護他的TGC,如果TGC被黑客獲取,黑客就會使用該TGC訪問所有的應用。
對SSO來說,這種風險是巨大的,因為SSO具有一種門檻效應,一旦登錄就會獲取相關服務的所有權限。
TGC保存在客戶端,其安全性完全有SSL保證。
TGC也有自己的存活周期,在CAS的web.xml中,可以通過grantingTimeout來設置CAS TGC的存活周期。
該周期需要慎重設置,既不影響用戶體驗,不能帶來過高的安全風險(避免被盜用)。
Service Ticket/Proxy Ticket的安全性
Service Ticket/Proxy Ticket是通過HTTP傳送的,因此網絡中的其他人是可以嗅探到他人的Ticket的。
CAS協議從以下幾個方面讓ST/PT更加安全。
- Service Ticket只能使用一次
- Service Ticket一段時間后失效
通過在web.xml中配置如下參數。
<context-param> <param-name>edu.yale.its.tp.cas.serviceTimeout</param-name> <param-value>300</param-value> </context-param>
- ST/PT的生成必須足夠隨機
避免被猜出生成規則
SAML
SAML是OASIS制定的安全性斷言標記語言,用於在復雜環境下交互用戶的身份識別信息,正在被越來越多的商用產品支持。
SAML與SOAP一樣,不考慮具體的傳輸協議,實際上可以與HTTP/SSL/JMS等任何傳輸協議捆綁。對於復雜的服務構型,由於不同服務可能有不同的協議,使用CAS將無法完成,因為CAS是基於HTTP/SSL上的,只有SAML能完成這項任務,因為其與傳輸協議無關。
最后,SAML是一種SSO標准而CVS是一種SSO實現,從CAS的RoadMap中可以看出,其也將很快支持SAML。
