Web應用系統的演化總是從簡(jiǎn)單到復雜,從單功能到多功能模塊再到多子系統方向發(fā)展。
.當前的大中型Web互聯(lián)網(wǎng)應用基本都是多系統組成的應用群,由多個(gè)web系統協(xié)同為用戶(hù)提供服務(wù)。
多系統應用群,必然意味著(zhù)各系統間既相對獨立,又保持著(zhù)某種聯(lián)系。
獨立,意味著(zhù)給用戶(hù)提供一個(gè)相對完整的功能服務(wù),比如C2C商城,比如B2C商城。聯(lián)系,意味著(zhù)從用戶(hù)角度看,不管企業(yè)提供的服務(wù)如何多樣化、系列化,在用戶(hù)看來(lái),仍舊是一個(gè)整體,用戶(hù)體驗不能受到影響。
譬如用戶(hù)的賬號管理,用戶(hù)應該有一個(gè)統一賬號,不應該讓用戶(hù)在每個(gè)子系統分別注冊、分別登錄、再分別登出。系統的復雜性不應該讓用戶(hù)承擔。
登錄用戶(hù)使用系統服務(wù),可以看做是一次用戶(hù)會(huì )話(huà)過(guò)程。在單Web應用中,用戶(hù)登錄、登錄狀態(tài)判斷、用戶(hù)登出等操作,已有很常規的解決方案實(shí)現。
在多系統應用群中,這個(gè)問(wèn)題就變得有些復雜,以前本不是問(wèn)題的問(wèn)題,現在可能就變成了一個(gè)重大技術(shù)問(wèn)題。我們要用技術(shù)手段,屏蔽系統底層本身的技術(shù)復雜性,給用戶(hù)提供自然超爽的用戶(hù)體驗。
這就是我們所說(shuō)的單點(diǎn)登錄問(wèn)題,即SSO(Single Sign On)。當然,我們這里主要討論的是Web系統,確切地講,應該叫Web SSO。
下面我們來(lái)看一個(gè)現實(shí)中SSO的例子,例如阿里系統: 阿里目前給用戶(hù)提供的服務(wù)很龐大,種類(lèi)也很繁多,我們看幾個(gè)典型系統應用: 淘寶應用、天貓應用、 阿里旅游。這些應用,當用戶(hù)訪(fǎng)問(wèn)時(shí),都需要登錄

顯然,對用戶(hù)來(lái)說(shuō),他不希望每個(gè)子應用分別登錄,因為這都是阿里服務(wù),在用戶(hù)看來(lái),就相當于一個(gè)大系統。
當我在一個(gè)應用如淘寶上登錄后,再訪(fǎng)問(wèn)阿里旅游、天貓等其它系統,我們發(fā)現,系統都顯示已登錄狀態(tài)。
當在任意一系統退出登錄后,再刷新訪(fǎng)問(wèn)其它系統,均已顯示登出狀態(tài)。
可以看出,阿里實(shí)現了SSO。實(shí)際上,幾乎所有提供復雜服務(wù)的互聯(lián)網(wǎng)公司,都實(shí)現了SSO,如阿里、百度、新浪、網(wǎng)易、騰訊、58...
SSO問(wèn)題,是大中型Web應用經(jīng)常碰到的問(wèn)題,是Java架構師需要掌握的必備技能之一,中高級以上Web工程師都應對它有個(gè)了解。

SSO有啥技術(shù)難點(diǎn)?為什么我們不能像解決單Web應用系統登錄那樣自然解決?為說(shuō)清楚這一問(wèn)題,我們得先了解下單應用系統下,用戶(hù)登錄的解決方案。
我們討論的應用是Web應用,大家知道,對于Web應用,系統是Browser/Server架構,Browser和Server之間的通信協(xié)議是HTTP協(xié)議。 HTTP是一個(gè)無(wú)狀態(tài)協(xié)議。即對服務(wù)器來(lái)說(shuō),每次收到的瀏覽器HTTP請求都是單一獨立的,服務(wù)器并不考慮兩次HTTP請求是否來(lái)自同一會(huì )話(huà),即HTTP協(xié)議是非連接會(huì )話(huà)狀態(tài)協(xié)議。
對于Web應用登錄,意味著(zhù)登錄成功后的后續訪(fǎng)問(wèn),可以看做是登錄用戶(hù)和服務(wù)端的一次會(huì )話(huà)交互過(guò)程,直到用戶(hù)登出結束會(huì )話(huà)。
如何在非連接會(huì )話(huà)協(xié)議之上,實(shí)現這種會(huì )話(huà)的管理? 我們需要額外的手段。
通常有兩種做法,一種是通過(guò)使用HTTP請求參數傳遞,這種方式對應用侵入性較大,一般不使用。
另一種方式就是通過(guò)cookie。
cookie是HTTP提供的一種機制,cookie代表一小撮數據。服務(wù)端通過(guò)HTTP響應創(chuàng )建好cookie后,瀏覽器會(huì )接收下來(lái),下次請求會(huì )自動(dòng)攜帶上返回給服務(wù)端。
利用這個(gè)機制,我們可以實(shí)現應用層的登錄會(huì )話(huà)狀態(tài)管理。例如我們可以把登錄狀態(tài)信息保存在cookie中,這是客戶(hù)端保存方式。
由于會(huì )話(huà)信息在客戶(hù)端,需要維護其安全性、需要加密保存、攜帶量會(huì )變大,這樣會(huì )影響http的處理效率,同時(shí)cookie的數據攜帶量也有一定的限制。
比較好的方式是服務(wù)端保存,cookie只保存會(huì )話(huà)信息的句柄。即在登錄成功后,服務(wù)端可以創(chuàng )建一個(gè)唯一登錄會(huì )話(huà),并把會(huì )話(huà)標識ID通過(guò)cookie返回給瀏覽器,瀏覽器下次訪(fǎng)問(wèn)時(shí)會(huì )自動(dòng)帶上這個(gè)ID,服務(wù)端根據ID即可判斷是此會(huì )話(huà)中的請求,從而判斷出是該用戶(hù),這種操作直到登出銷(xiāo)毀會(huì )話(huà)為止。
令人高興的是,我們使用的Web應用服務(wù)器一般都會(huì )提供這種會(huì )話(huà)基礎服務(wù),如Tomcat的Session機制。也就是說(shuō),應用開(kāi)發(fā)人員不必利用Cookie親自代碼實(shí)現會(huì )話(huà)的創(chuàng )建、維護和銷(xiāo)毀等整個(gè)生命周期管理,這些內容服務(wù)器Session已經(jīng)提供好了,我們只需正確使用即可。
當然,為了靈活性和效率,開(kāi)發(fā)人員也可直接使用cookie實(shí)現自己的這種會(huì )話(huà)管理。
對于Cookie,處于安全性考慮,它有一個(gè)作用域問(wèn)題,這個(gè)作用域由屬性Domain和Path共同決定的。也就是說(shuō),如果瀏覽器發(fā)送的請求不在此Cookie的作用域范圍內,請求是不會(huì )帶上此Cookie的。
Path是訪(fǎng)問(wèn)路徑,我們可以定義/根路徑讓其作用所有路徑,Domain就不一樣了。我們不能定義頂級域名如.com,讓此Cookie對于所有的com網(wǎng)站都起作用,最大范圍我們只能定義到二級域名如.taobao.com,而通常,企業(yè)的應用群可能包含有多個(gè)二級域名。

這時(shí),解決單系統會(huì )話(huà)問(wèn)題的Cookie機制不起作用了,多系統不能共享同一會(huì )話(huà),這就是問(wèn)題的所在!
當然,有的同學(xué)會(huì )說(shuō):我把所有的應用統一用三級域名來(lái)表示,如a . t a o b a o . c o m、b . t a o b a o . c o m、c . t a o b a o . c o m或干脆用路徑來(lái)區分不同的應用如w w w . t a o b a o . c om \ a、w w w . t a o b a o . c o m \ b、w w w . t a o b a o . c o m \ c,這樣cookie不就可以共享了么?
事實(shí)是成立的,但現實(shí)應用中,多域名策略是普遍存在的,也有商業(yè)角度的考慮,這些我們必須要面對。
退一步講,即使cookie可以共享了,服務(wù)端如何識別處理這個(gè)會(huì )話(huà)?這時(shí),我們是不能直接使用服務(wù)器所提供的Session機制的,Session是在單一應用范圍內,共享Session需要特殊處理。
更復雜的情況是,通常這些子系統可能是異構的,session實(shí)現機制并不相同,如有的是Java系統,有的是PHP系統。共享Session對原系統入侵性很大。
至此,SSO技術(shù)問(wèn)題這里講清楚了。那我們有沒(méi)有更好的通用解決方案?答案肯定是有的,但比較復雜,這也是我們專(zhuān)題討論的理由??傮w來(lái)說(shuō),我們需要一個(gè)中央認證服務(wù)器,來(lái)統一集中處理各子系統的登錄請求。這是入門(mén),后續會(huì )有系列文章深層次探討。

聯(lián)系客服