? ? ? ? ?“號(hào)外號(hào)外,驚天大消息,人類要開(kāi)始做SSO系統(tǒng)啦”。一大清早就聽(tīng)見(jiàn)PHP在哪里吆喝道。
????????“大清早還讓不讓人睡覺(jué)了”,C惡狠狠的說(shuō)?!半m說(shuō)你是世界上最好的語(yǔ)言,但是也別到處賣弄啊,SSO是個(gè)什么鬼,說(shuō)人話”
? ? ? ?PHP:大傻帽,SSO都不知道啊。Single Sign One 啊。單點(diǎn)登錄啊。
? ? ? ? C:哈哈哈哈哈哈哈哈哈。讓我笑一會(huì)兒。不是就個(gè)登錄么?至于說(shuō)的這么高大上啊。你去看看用我寫的訂單系統(tǒng)去,每天有多少人登錄。他們想訪問(wèn)我的系統(tǒng)時(shí),必須輸入用戶名和密碼,然后我進(jìn)行驗(yàn)證,驗(yàn)證通過(guò)后我就在我這邊建立一個(gè)叫做session的東西,然后把sessionId通過(guò)cookie發(fā)送給瀏覽器,下次他們?cè)诘卿浀臅r(shí)候會(huì)帶著cookie一起發(fā)過(guò)來(lái),我從cookie中拿到sessionId就知道他們已經(jīng)登錄啦。通過(guò)cookie和session就可以把無(wú)狀態(tài)通信的轉(zhuǎn)換成有狀態(tài)的啦,是不是so easy啊。C說(shuō)完滿臉自豪的樣子。
????????PHP:你說(shuō)的登錄沒(méi)問(wèn)題啊,可是人們并不是每天只支付你的訂單系統(tǒng)哦。他們可能還需要登錄用戶系統(tǒng),可能還需要登錄庫(kù)存系統(tǒng)呢。比如說(shuō)有個(gè)叫小明的用戶登錄了你的訂單系統(tǒng),然后想去看庫(kù)存系統(tǒng),發(fā)現(xiàn)又讓登錄,再次輸入用戶名密碼,然后又去登錄用戶系統(tǒng),又輸一次用戶名密碼,去訪問(wèn)財(cái)務(wù)系統(tǒng),有來(lái)一遍。。。。。如果有一萬(wàn)個(gè)服務(wù)需要訪問(wèn),那估計(jì)別干別的啦。
????????C:這個(gè)這個(gè)這個(gè)。。。
????????PHP:是吧,本來(lái)就是同一個(gè)用戶,不論是訪問(wèn)訂單系統(tǒng)也好,庫(kù)存系統(tǒng)也罷,都是我們自己內(nèi)部的系統(tǒng),所以在一個(gè)地方登陸了就能自動(dòng)登陸別的系統(tǒng)不就好了么。這就是人類要開(kāi)始搞SSO得原因嘍。
????????C:哇,果然是高大上的樣子。可是要怎么實(shí)現(xiàn)呢?感覺(jué)超級(jí)難得樣子呢。
????????PHP:你剛剛不是還洋洋得意的把登錄的原理說(shuō)了一遍么,自己好好想想呢。
????????C:嗯。對(duì)。登錄就是通過(guò)cookie和session來(lái)實(shí)現(xiàn)有狀態(tài)的。我可以把cookie做共享啊。登錄完訂單系統(tǒng)之后我就有了cookie,去登錄庫(kù)存系統(tǒng)的時(shí)候我把cookie帶過(guò)去不就行了么?
????????PHP:NO! NO!NO! 你這樣是有問(wèn)題得。1,cookie是不能跨域的,比如說(shuō)a.com產(chǎn)生的cookie是不能傳遞給b.com的。2,就算cookie可以帶過(guò)來(lái)了,可是庫(kù)存系統(tǒng)并沒(méi)有session啊,如何驗(yàn)證呢?
????????C:這個(gè)簡(jiǎn)單啊。1,我們可以讓所有的系統(tǒng)都掛在同一個(gè)一級(jí)域名下啊。比如我叫a.corp.com,庫(kù)存系統(tǒng)叫b.corp.com,財(cái)務(wù)系統(tǒng)叫c.corp.com,這樣cookie不就能共享了嘛。2,既然cookie能共享,那session當(dāng)然也能共享。之前把session存在自己的內(nèi)存里,別人拿不到,我從內(nèi)存里拿出來(lái)放在一個(gè)大家都能拿到的地方不就行了么?就像下面這樣。哈哈哈我是不是很聰明。

????????這個(gè)時(shí)候一旁的Java終于按奈不住了:你的系統(tǒng)中可能有很多個(gè)系統(tǒng),而且各自實(shí)現(xiàn)的語(yǔ)言可能也不盡相同,有用C++的,有用PHP的,有用GO的,也有用Java的,共享session就會(huì)顯得很麻煩啦。各個(gè)系統(tǒng)還得自己維護(hù)用戶。其實(shí)啦,人們做SSO的初衷就是想消除多賬號(hào)的問(wèn)題,不用各自系統(tǒng)維護(hù)用戶的信息。他們將會(huì)建立一個(gè)統(tǒng)一的認(rèn)證中心,所用的用戶的認(rèn)證工作都交給這個(gè)認(rèn)證中心來(lái)完成就OK啦。
????????PHP和C:哇。好高大上哦,大佬,給我們講講唄。
????????JAVA:看你們這么好學(xué),聽(tīng)我娓娓道來(lái)。
????????比如說(shuō)現(xiàn)在用戶第一次像訂單系統(tǒng)發(fā)起了訪問(wèn):www.a.corp.com,這個(gè)時(shí)候訂單系統(tǒng)發(fā)現(xiàn)用戶沒(méi)有登錄的話,那他需要做的一項(xiàng)操作就是重定向認(rèn)證中心:www.sso.com/login?redirect=www.a.corp.com。其中www.sso.com/login就是認(rèn)證中心的登錄地址,redirect=www.a.corp.com就是登錄完成后需要跳轉(zhuǎn)到的地址。在認(rèn)證中心登錄之后認(rèn)證中心會(huì)做以下幾件事情:
1,建立一個(gè)session
2,發(fā)放ticket
3,重定向到你的地址,并在瀏覽器種下cookie信息。注意這個(gè)cookie是sso服務(wù)器的cookie哦。如:ssoid=1,domain=sso.com
大致流程如下:

需要注意的有兩點(diǎn):
1,進(jìn)行了兩次重定向哦。第一次是重定向到SSO的服務(wù)器,第二次是重定向我們的后端服務(wù)器。
2,流程完成后再瀏覽器種了兩個(gè)cookie,一個(gè)是sso服務(wù)器的cookie,一個(gè)是訂單系統(tǒng)的cookie。
????????PHP和C聽(tīng)畢,拍手稱快:大哥真不愧是世界上最好的語(yǔ)言呢。C接著問(wèn),那接著庫(kù)存系統(tǒng)會(huì)發(fā)生什么呢?
????????Java:這個(gè)簡(jiǎn)單啊。還記得上面在瀏覽器的cookie嗎?看下面的流程。

你倆想想,這個(gè)流程之后瀏覽器會(huì)有幾個(gè)cookie呢?
????????PHP和C爭(zhēng)先恐后的喊道:我知道我知道。應(yīng)該是有三個(gè)的。一個(gè)是認(rèn)證中心SSO的cookie: domain sso.com,一個(gè)是訂單系統(tǒng)的cookie:a.corp.com,還有一個(gè)是庫(kù)存系統(tǒng)的cookie:domain b.corp.com。實(shí)質(zhì)上就是保存了一個(gè)認(rèn)證中心的cookie和多個(gè)子系統(tǒng)的cookie而已啦
????????Java:孺子可教也。一般我們稱SSO的cookie的對(duì)應(yīng)的會(huì)話成為全局會(huì)話,各自子系統(tǒng)cookie對(duì)應(yīng)的會(huì)話稱為局部會(huì)話。
????????PHP和C:聽(tīng)起來(lái)是高大上,不會(huì)感覺(jué)好繞啊。又是各種重定向,又是各種cookie的,我們都懵逼了,實(shí)現(xiàn)起來(lái)豈不是更加的困難了。
????????Java:你們真是out啊,聽(tīng)說(shuō)過(guò)CAS(Central Authentication Service)嗎?耶魯大學(xué)提出的一套關(guān)于SSO的解決方案,現(xiàn)在都已經(jīng)廣泛的推廣啦。大家都在用啦。
????????PHP和C聽(tīng)畢,感嘆道:學(xué)無(wú)止境啊。比我優(yōu)秀的人都還在不斷進(jìn)步,我們還有不學(xué)習(xí)的道理啊。