本文給出了現有的單點登入成熟實作CAS的基本原理,體系結構,認證過程,以及業界方案的選型,用于指導下一步的概要設計。
基本概念
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進行開發。
http://www.jasig.org/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。