在結(jié)構(gòu)設(shè)計(jì)上復(fù)用性是一個(gè)很重要的特征,昨天半夜我發(fā)的系統(tǒng)地非侵入性也是很重要的,有同志邀我看看他的SSO系統(tǒng),不過(guò)看后都我覺(jué)得不甚滿(mǎn)意,如果要服用的話需要把分散的代碼一點(diǎn)點(diǎn)摳出來(lái),然后經(jīng)過(guò)反復(fù)的修改調(diào)試后才能在新的系統(tǒng)中使用,那位老兄的SSO系統(tǒng)功能可能確實(shí)強(qiáng)大,而且還用了新技術(shù),不過(guò)在復(fù)用性上我看還是沒(méi)有擺脫集成上的痛苦,作過(guò)系統(tǒng)集成的同學(xué)們肯定對(duì)此深有感觸。
昨天才批判了很多同學(xué)寫(xiě)東西語(yǔ)焉不詳,結(jié)果回頭就自己給了自己一耳巴子,上幾篇關(guān)于SSO的描述都不夠詳細(xì),于是這里在手把手系列里我們來(lái)一起看看如何設(shè)計(jì)一個(gè)高度可服用的SSO模塊,這里我們假設(shè)所有的站點(diǎn)都使用.NET,因?yàn)槌墒斓腟SO需要和采用各種不同技術(shù)的站點(diǎn)之間實(shí)現(xiàn)SSO,于是有JAVA,PHP,COM+,.NET多種形式的PSO模塊。這里我們精力有限,所以先假設(shè)都用.NET,如果你會(huì)JAVA也可以自己用java來(lái)實(shí)現(xiàn)PSO。
一般來(lái)說(shuō)單點(diǎn)認(rèn)證都需要兩端來(lái)完成,在認(rèn)證中心端的我們稱(chēng)之為SSO,在網(wǎng)站端的模塊我們稱(chēng)之為PSO。兩個(gè)模塊之間采用二次重定向技術(shù)來(lái)實(shí)現(xiàn)同步兩端票據(jù)的方式來(lái)實(shí)現(xiàn)單點(diǎn)登陸
首先我們就來(lái)看看這兩個(gè)模塊式如何配合來(lái)完成單點(diǎn)認(rèn)證的
第一個(gè)場(chǎng)景是用戶(hù)首先訪問(wèn)認(rèn)證中心登陸再去進(jìn)入成員網(wǎng)站的情況:

首先是登陸后產(chǎn)生一個(gè)SSO的票據(jù),這個(gè)票據(jù)是最重要的,因?yàn)樗菦Q定用戶(hù)是否登陸的關(guān)鍵。這個(gè)票據(jù)可以是Cookie,也可以是Session,我比較傾向于Cookie,因?yàn)楝F(xiàn)在有3DES加密,加密后篡改Cookie幾乎成為不可能,所以無(wú)論是對(duì)于服務(wù)器負(fù)擔(dān)來(lái)說(shuō)還是安全性都是Cookie比較好,可能人認(rèn)為萬(wàn)一不支持Cookie呢,不過(guò)我想Demo應(yīng)該沒(méi)問(wèn)題吧,大不了我設(shè)計(jì)成兩個(gè)都支持:},
PS,為什么不用非對(duì)稱(chēng)加密?其實(shí)那個(gè)效率不高,3DES的安全性已經(jīng)足夠了,至少現(xiàn)在還沒(méi)有人宣稱(chēng)能破解
在登陸后就可以通知用戶(hù)你已經(jīng)登陸了,現(xiàn)在你可以去訪問(wèn)成員站點(diǎn)了,這個(gè)時(shí)候用戶(hù)點(diǎn)擊了成員站點(diǎn)的URL,進(jìn)去了,這個(gè)時(shí)候首先就需要接受PSO組件的盤(pán)查,你有沒(méi)有PSO的票據(jù)呢?很顯然是沒(méi)有的,所以這個(gè)時(shí)候請(qǐng)求就被Redirect回了認(rèn)證中心,認(rèn)證中心檢查用戶(hù)已經(jīng)有了SSO的票據(jù)了,認(rèn)為用戶(hù)已經(jīng)登錄了,就把用戶(hù)的SSO票據(jù)附加在URL后邊然后Redirect回成員站點(diǎn),成員站點(diǎn)的PSO這個(gè)時(shí)候獲取到了SSO票據(jù),于是知道了用戶(hù)已經(jīng)在認(rèn)證端登錄了,于是就創(chuàng)建一個(gè)PSO票據(jù),然后返回給用戶(hù)他所請(qǐng)求的內(nèi)容。所以我們來(lái)看看其實(shí)PSO的邏輯更加復(fù)雜一點(diǎn)。
SSO的邏輯:
PSO的邏輯:
這里我們可以看到其實(shí)兩個(gè)模塊的功能都不算復(fù)雜,這里存在幾個(gè)現(xiàn)實(shí)的問(wèn)題,第一個(gè)是加密問(wèn)題,票據(jù)需要加密,傳輸?shù)腢RL也需要加密。
還有一個(gè)就是上一次我上篇文章里說(shuō)的,在SSO把票據(jù)通過(guò)URL發(fā)送給PSO的時(shí)候,如果我們能夠截獲這個(gè)URL,不管他加沒(méi)有加密,在下一次我們直接用這個(gè)URL去訪問(wèn)站點(diǎn)的時(shí)候因?yàn)橐呀?jīng)包含SSO票據(jù)了,所以PSO會(huì)認(rèn)為已經(jīng)登陸了而直接產(chǎn)生PSO票據(jù)然后就讓用戶(hù)進(jìn)去了,這顯然是一個(gè)漏洞。所以呢,我們需要在這里給這個(gè)URL加一點(diǎn)鹽值(所謂鹽值其實(shí)就是加點(diǎn)料),我們通過(guò)在URL里加入時(shí)間戳來(lái)讓這個(gè)URL具備時(shí)間限制,這個(gè)樣子URL具備失效期,過(guò)了這個(gè)時(shí)間即使截獲到了這個(gè)URL也完全沒(méi)有作用了。