1. 程式人生 > >SSO單點登錄 與 CAS

SSO單點登錄 與 CAS

定義 顯示 多域名 這就是我 機制 旅遊 目前 功能 如果

本文轉載自http://www.imooc.com/u/2245641/articles
非常好的sso單點登錄理解文章
作者: 常明,Java架構師


技術分享圖片

Web應用系統的演化總是從簡單到復雜,從單功能到多功能模塊再到多子系統方向發展。

技術分享圖片

.當前的大中型Web互聯網應用基本都是多系統組成的應用群,由多個web系統協同為用戶提供服務。

多系統應用群,必然意味著各系統間既相對獨立,又保持著某種聯系。

獨立,意味著給用戶提供一個相對完整的功能服務,比如C2C商城,比如B2C商城。聯系,意味著從用戶角度看,不管企業提供的服務如何多樣化、系列化,在用戶看來,仍舊是一個整體,用戶體驗不能受到影響。

譬如用戶的賬號管理,用戶應該有一個統一賬號,不應該讓用戶在每個子系統分別註冊、分別登錄、再分別登出。系統的復雜性不應該讓用戶承擔。
技術分享圖片

登錄用戶使用系統服務,可以看做是一次用戶會話過程。在單Web應用中,用戶登錄、登錄狀態判斷、用戶登出等操作,已有很常規的解決方案實現。

在多系統應用群中,這個問題就變得有些復雜,以前本不是問題的問題,現在可能就變成了一個重大技術問題。我們要用技術手段,屏蔽系統底層本身的技術復雜性,給用戶提供自然超爽的用戶體驗。

這就是我們所說的單點登錄問題,即SSO(Single Sign On)。當然,我們這裏主要討論的是Web系統,確切地講,應該叫Web SSO。
技術分享圖片
下面我們來看一個現實中SSO的例子,例如阿裏系統:

阿裏目前給用戶提供的服務很龐大,種類也很繁多,我們看幾個典型系統應用:www.taobao.com 淘寶應用、www.tmall.com 天貓應用、
www.alitrip.com 阿裏旅遊。這些應用,當用戶訪問時,都需要登錄
技術分享圖片


顯然,對用戶來說,他不希望每個子應用分別登錄,因為這都是阿裏服務,在用戶看來,就相當於一個大系統。

當我在一個應用如淘寶上登錄後,再訪問阿裏旅遊、天貓等其它系統,我們發現,系統都顯示已登錄狀態。

當在任意一系統退出登錄後,再刷新訪問其它系統,均已顯示登出狀態。

可以看出,阿裏實現了SSO。實際上,幾乎所有提供復雜服務的互聯網公司,都實現了SSO,如阿裏、百度、新浪、網易、騰訊、58...

SSO問題,是大中型Web應用經常碰到的問題,是Java架構師需要掌握的必備技能之一,中高級以上Web工程師都應對它有個了解。
技術分享圖片
SSO有啥技術難點?為什麽我們不能像解決單Web應用系統登錄那樣自然解決?為說清楚這一問題,我們得先了解下單應用系統下,用戶登錄的解決方案。

我們討論的應用是Web應用,大家知道,對於Web應用,系統是Browser/Server架構,Browser和Server之間的通信協議是HTTP協議。

HTTP是一個無狀態協議。即對服務器來說,每次收到的瀏覽器HTTP請求都是單一獨立的,服務器並不考慮兩次HTTP請求是否來自同一會話,即HTTP協議是非連接會話狀態協議。

對於Web應用登錄,意味著登錄成功後的後續訪問,可以看做是登錄用戶和服務端的一次會話交互過程,直到用戶登出結束會話。

如何在非連接會話協議之上,實現這種會話的管理? 我們需要額外的手段。

通常有兩種做法,一種是通過使用HTTP請求參數傳遞,這種方式對應用侵入性較大,一般不使用。

另一種方式就是通過cookie。

cookie是HTTP提供的一種機制,cookie代表一小撮數據。服務端通過HTTP響應創建好cookie後,瀏覽器會接收下來,下次請求會自動攜帶上返回給服務端。

利用這個機制,我們可以實現應用層的登錄會話狀態管理。例如我們可以把登錄狀態信息保存在cookie中,這是客戶端保存方式。

由於會話信息在客戶端,需要維護其安全性、需要加密保存、攜帶量會變大,這樣會影響http的處理效率,同時cookie的數據攜帶量也有一定的限制。

比較好的方式是服務端保存,cookie只保存會話信息的句柄。即在登錄成功後,服務端可以創建一個唯一登錄會話,並把會話標識ID通過cookie返回給瀏覽器,瀏覽器下次訪問時會自動帶上這個ID,服務端根據ID即可判斷是此會話中的請求,從而判斷出是該用戶,這種操作直到登出銷毀會話為止。

令人高興的是,我們使用的Web應用服務器一般都會提供這種會話基礎服務,如Tomcat的Session機制。也就是說,應用開發人員不必利用Cookie親自代碼實現會話的創建、維護和銷毀等整個生命周期管理,這些內容服務器Session已經提供好了,我們只需正確使用即可。

當然,為了靈活性和效率,開發人員也可直接使用cookie實現自己的這種會話管理。

對於Cookie,處於安全性考慮,它有一個作用域問題,這個作用域由屬性Domain和Path共同決定的。也就是說,如果瀏覽器發送的請求不在此Cookie的作用域範圍內,請求是不會帶上此Cookie的。

Path是訪問路徑,我們可以定義/根路徑讓其作用所有路徑,Domain就不一樣了。我們不能定義頂級域名如.com,讓此Cookie對於所有的com網站都起作用,最大範圍我們只能定義到二級域名如.taobao.com,而通常,企業的應用群可能包含有多個二級域名,如taobao.com、tmail.com、alitrip.com等等。
技術分享圖片
這時,解決單系統會話問題的Cookie機制不起作用了,多系統不能共享同一會話,這就是問題的所在!
當然,有的同學會說:我把所有的應用統一用三級域名來表示,如a.taobao.com、b.taobao.com、c.taobao.com或幹脆用路徑來區分不同的應用如www.taobao.com\a、www.taobao.com\b、www.taobao.com\c,這樣cookie不就可以共享了麽?

事實是成立的,但現實應用中,多域名策略是普遍存在的,也有商業角度的考慮,這些我們必須要面對。

退一步講,即使cookie可以共享了,服務端如何識別處理這個會話?這時,我們是不能直接使用服務器所提供的Session機制的,Session是在單一應用範圍內,共享Session需要特殊處理。

更復雜的情況是,通常這些子系統可能是異構的,session實現機制並不相同,如有的是Java系統,有的是PHP系統。共享Session對原系統入侵性很大。

至此,SSO技術問題這裏講清楚了。那我們有沒有更好的通用解決方案?答案肯定是有的,但比較復雜,這也是我們專題討論的理由。總體來說,我們需要一個中央認證服務器,來統一集中處理各子系統的登錄請求。這是入門,後續會有系列文章深層次探討。


技術分享圖片

SSO單點登錄 與 CAS