本文分兩部分
1.轉(zhuǎn)他人的文章肯腕,詳細(xì)介紹了跨站單點(diǎn)登錄的原理和解決方案
2.我自己寫(xiě)代碼,著重介紹里面的重點(diǎn)部分
1:
假設(shè)我們需要在以下這些站之間實(shí)現(xiàn)單點(diǎn)登錄
www.onmpw1.com
www.onmpw2.com
www.onmpw3.com
對(duì)于這種情況堡僻,我們有兩種實(shí)現(xiàn)方式糠惫,其中我們先來(lái)介紹實(shí)現(xiàn)比較簡(jiǎn)單的方式。
方式一
為了實(shí)現(xiàn)單點(diǎn)登錄钉疫,當(dāng)用戶(hù)登錄其中的任何一個(gè)站點(diǎn)時(shí)硼讽,我們需要針對(duì)其他每個(gè)站點(diǎn)在瀏覽器端設(shè)置cookie信息。
如果用戶(hù)在onmpw1站點(diǎn)進(jìn)行登錄牲阁,登錄成功授權(quán)以后固阁,瀏覽器將會(huì)存儲(chǔ)一份兒onmpw1站點(diǎn)的cookie信息壤躲。同時(shí),為了可以登錄onmpw2和onmpw3备燃,我們需要在設(shè)置onmpw1的cookie的同事也對(duì)onmpw2和onmpw3進(jìn)行cookie設(shè)置碉克。因此在對(duì)onmpw1進(jìn)行響應(yīng)之前,我們需要先跳轉(zhuǎn)到onmpw2和onmpw3站點(diǎn)去設(shè)置cookie信息并齐。
下圖是對(duì)于兩個(gè)站點(diǎn)的單點(diǎn)登錄模型(三個(gè)的圖畫(huà)起來(lái)比較麻煩漏麦,為了節(jié)省時(shí)間,就用兩個(gè)來(lái)表示冀膝,但是原理是相同的)
此種情況的驗(yàn)證步驟是這樣的:
一唁奢、用戶(hù)向www.onmpw1.com(以下簡(jiǎn)稱(chēng)onmpw1)請(qǐng)求一個(gè)需要驗(yàn)證的頁(yè)面。
[狀態(tài): 瀏覽器還沒(méi)有驗(yàn)證的cookie信息]
二窝剖、瀏覽器向onmpw1發(fā)送請(qǐng)求(該請(qǐng)求沒(méi)有cookie信息麻掸,因?yàn)樗€沒(méi)有存儲(chǔ)所屬域?yàn)閛nmpw1.com的cookie信息)。
[狀態(tài): 瀏覽器還沒(méi)有驗(yàn)證的cookie信息]
三赐纱、onmpw1發(fā)現(xiàn)在請(qǐng)求中沒(méi)有帶cookie信息脊奋,所以它將請(qǐng)求重定向到登錄頁(yè)面
[狀態(tài): 瀏覽器還沒(méi)有驗(yàn)證的cookie信息]
四、用戶(hù)提交了登錄所需驗(yàn)證的信息并且點(diǎn)擊登錄按鈕疙描,瀏覽器發(fā)送一個(gè)post請(qǐng)求到onmpw1诚隙。
[狀態(tài): 瀏覽器還沒(méi)有驗(yàn)證的cookie信息]
五、onmpw1收到提交的驗(yàn)證信息起胰,開(kāi)始驗(yàn)證這些信息淮菠。如果驗(yàn)證成功涯穷,則標(biāo)記該用戶(hù)已經(jīng)登錄。然后會(huì)創(chuàng)建帶有登錄用戶(hù)信息的cookie,并將其加入響應(yīng)信息中速梗。
[狀態(tài): 瀏覽器還沒(méi)有驗(yàn)證的cookie信息]
六徽龟、onmpw1暫時(shí)還不去響應(yīng)瀏覽器的請(qǐng)求绩聘。這時(shí)它將會(huì)向?yàn)g覽器發(fā)送重定向到www.onmpw2.com(以下簡(jiǎn)稱(chēng)onmpw2)的命令踢代,并且還帶有在onmpw2站點(diǎn)需要返回的url地址,該地址為最初onmpw1中的戒劫。因?yàn)閏ookie信息已經(jīng)在響應(yīng)信息中半夷,所以這個(gè)cookie也被發(fā)送給瀏覽器了。
[狀態(tài): 瀏覽器還沒(méi)有驗(yàn)證的cookie信息]
七迅细、瀏覽器接收道帶有驗(yàn)證的cookie信息和重定向到onmpw2的命令的響應(yīng)信息以后巫橄,將cookie信息的域設(shè)置為onmpw2存儲(chǔ)到本地,并且想onmpw2發(fā)送請(qǐng)求茵典。這個(gè)請(qǐng)求中會(huì)帶有剛才的cookie信息嗦随。
[狀態(tài):瀏覽器中已經(jīng)有所屬域?yàn)閛nmpw2的cookie信息]
八、onmpw2立刻會(huì)重定向到需要返回的url地址,并且通過(guò)讀取瀏覽器發(fā)送的cookie信息枚尼,獲取到onmpw1的cookie贴浙。并將這cookie也一同發(fā)送給瀏覽器。
[狀態(tài):瀏覽器中已經(jīng)有所屬域?yàn)閛nmpw2的cookie信息]
九署恍、瀏覽器在接受到這些信息以后崎溃,會(huì)將所屬域?yàn)閛nmpw1的cookie存儲(chǔ)在本地。并且再次向onmpw1發(fā)送一個(gè)帶有cookie信息的請(qǐng)求盯质。
[狀態(tài):瀏覽器中已經(jīng)有所屬域?yàn)閛nmpw2和onmpw1的cookie信息]
十袁串、onmpw1接收到驗(yàn)證信息以后,知道驗(yàn)證cookie已經(jīng)設(shè)置成功呼巷。此時(shí)onmpw1會(huì)返回相應(yīng)的請(qǐng)求界面囱修,而不再是登錄界面。
[狀態(tài):瀏覽器中已經(jīng)有所屬域?yàn)閛nmpw2和onmpw1的cookie信息]
所以說(shuō)王悍,當(dāng)用戶(hù)再次訪問(wèn)onmpw2的時(shí)候破镰,cookie信息已經(jīng)存儲(chǔ)到瀏覽器中了。這時(shí)onmpw2會(huì)在cookie中讀取到登錄的用戶(hù)的信息压储,然后提供相應(yīng)的界面給瀏覽器鲜漩。
這樣,單點(diǎn)登錄就已經(jīng)設(shè)置成功了集惋。在本例中孕似,按照上述步驟,登錄onmpw1以后刮刑,onmpw2和onmpw3就可以同時(shí)實(shí)現(xiàn)登錄了喉祭。
如何退出登錄
既然我們已經(jīng)實(shí)現(xiàn)了單點(diǎn)登錄,但是我們還得考慮退出的問(wèn)題雷绢。既然是同時(shí)登錄的泛烙,那總不能在退出的時(shí)候一個(gè)一個(gè)的退出吧!所以說(shuō)我們還要設(shè)置單點(diǎn)退出习寸。
要想實(shí)現(xiàn)單點(diǎn)退出,在本例中傻工,我們需要做的是當(dāng)在一個(gè)站點(diǎn)退出的時(shí)候霞溪,其他兩個(gè)站點(diǎn)的cookie同樣也需要在瀏覽器中清除。這樣才可以實(shí)現(xiàn)單點(diǎn)退出中捆。
這樣其實(shí)也很簡(jiǎn)單鸯匹,在理解了上述單點(diǎn)登錄的流程以后,單點(diǎn)退出只是按照上面的步驟將設(shè)置驗(yàn)證cookie改成從響應(yīng)信息中移除cookie就可以實(shí)現(xiàn)了泄伪。
對(duì)于這種情況殴蓬,不管是單點(diǎn)登錄也好,還是單點(diǎn)退出。都存在一個(gè)問(wèn)題染厅,在本例中我們只是有三個(gè)站點(diǎn)痘绎。如果說(shuō)我們整個(gè)系統(tǒng)有10個(gè)20個(gè)或者更多站點(diǎn),那像我們這樣來(lái)回的重定向會(huì)很影響效率肖粮。
方式二
接下來(lái)我們來(lái)介紹另一種方式孤页。這種方式需要我們借助一個(gè)單獨(dú)的SSO服務(wù),專(zhuān)門(mén)做驗(yàn)證用涩馆。而且我們還需要對(duì)于不同的站點(diǎn)的用戶(hù)要有一個(gè)統(tǒng)一的用戶(hù)數(shù)據(jù)行施。相對(duì)于前一種方式——瀏覽器需要存儲(chǔ)每個(gè)站點(diǎn)的cookie——來(lái)說(shuō),這種方式瀏覽器只需要存儲(chǔ)SSO服務(wù)站點(diǎn)的cookie信息魂那。將這個(gè)cookie信息用于其他站點(diǎn)從而實(shí)現(xiàn)單點(diǎn)登錄蛾号。我們暫且將這個(gè)SSO服務(wù)站點(diǎn)成為www.SSOsite.com(以下簡(jiǎn)稱(chēng)SSOsite)。
在這種模型下涯雅,針對(duì)任何站點(diǎn)的請(qǐng)求都將會(huì)先重定向到SSOsite去驗(yàn)證一個(gè)身份驗(yàn)證cookie是否存在鲜结。如果存在,則驗(yàn)證過(guò)的頁(yè)面將會(huì)發(fā)送給瀏覽器斩芭。否則用戶(hù)將會(huì)被重定向到登錄頁(yè)面轻腺。
為了理解此種方式,現(xiàn)在假設(shè)我們來(lái)運(yùn)用這種模型實(shí)現(xiàn)以下兩個(gè)站點(diǎn)的單點(diǎn)登錄划乖。
www.onmpw1.com(以下簡(jiǎn)稱(chēng)onmpw1)
www.onmpw2.com(以下簡(jiǎn)稱(chēng)onmpw2)
并且我們還有一個(gè)專(zhuān)門(mén)用來(lái)進(jìn)行驗(yàn)證的服務(wù)站點(diǎn)www.SSOsite.com(以下簡(jiǎn)稱(chēng)SSOsite) 贬养。
第一部分
實(shí)現(xiàn)流程
·用戶(hù)請(qǐng)求onmpw1的一個(gè)需要驗(yàn)證的頁(yè)面
·onmpw1向?yàn)g覽器發(fā)送重定向到SSOsite的命令。并且在地址中添加一個(gè)返回地址(ReturnUrl)參數(shù)query string琴庵,該參數(shù)的值就是最初向onmpw1請(qǐng)求的地址误算。
·SSOsite會(huì)在請(qǐng)求中檢查是否有身份驗(yàn)證cookie,或者任何用戶(hù)token迷殿。沒(méi)有這些信息儿礼,則會(huì)再次重定向到onmpw1,在重定向到onmpw1中的請(qǐng)求中會(huì)帶有參數(shù)讓用戶(hù)登錄的url參數(shù)和最初的瀏覽器請(qǐng)求onmpw1的地址——ReturnUrl庆寺。
·onmpw1會(huì)檢測(cè)從SSOsite重定向來(lái)的請(qǐng)求的參數(shù)蚊夫。這時(shí)onmpw1了解到該用戶(hù)需要登錄,因此onmpw1會(huì)重定向到登錄界面懦尝,并且通知瀏覽器該請(qǐng)求不用再重定向到SSOsite知纷。
第二部分
·用戶(hù)提供了身份驗(yàn)證信息并且點(diǎn)擊了登錄按鈕。現(xiàn)在不會(huì)再去重定向到SSOsite陵霉。這時(shí)琅轧,onmpw1調(diào)用SSOsite 中的web/WCF服務(wù)去檢查用戶(hù)提供的身份驗(yàn)證信息。成功驗(yàn)證踊挠,會(huì)將帶有token屬性的用戶(hù)對(duì)象返回給onmpw1乍桂。而這個(gè)token是每一次用戶(hù)登錄都會(huì)生成的。
·onmpw1標(biāo)記用戶(hù)已經(jīng)登錄成功,然后會(huì)生成一個(gè)URL地址睹酌,該地址會(huì)帶有用戶(hù)token权谁,重定向到SSOsite。
·SSOsite檢查收到的URL地址忍疾,會(huì)在其中發(fā)現(xiàn)用戶(hù)token闯传。通過(guò)該token可以知道用戶(hù)已經(jīng)成功登錄onmpw1了,所以SSOsite需要準(zhǔn)備驗(yàn)證的cookie信息卤妒。因此甥绿,它會(huì)使用token在緩存中取出用戶(hù)信息來(lái)生成cookie信息,而且還會(huì)在cookie中設(shè)置一些其他的信息(例如過(guò)期時(shí)間等)则披。然后把cookie加入到響應(yīng)信息中共缕。最后重定向到最初的ReturnUrl地址。同時(shí)token還是要被加在query string中帶過(guò)去的士复。
·瀏覽器得到重定向到onmpw1的命令图谷,并且從SSOsite中得到cookie信息。因此瀏覽器將所屬域?yàn)镾SOsite的cookie保存在本地阱洪。然后帶著token去請(qǐng)求onmpw1便贵。
·現(xiàn)在onmpw1看到用戶(hù)token在query string 參數(shù)中,然后會(huì)再次通過(guò)web/WCF服務(wù)去在SSOsite上驗(yàn)證token冗荸。驗(yàn)證成功以后會(huì)將最初剛開(kāi)始請(qǐng)求的頁(yè)面發(fā)送給瀏覽器用于向用戶(hù)輸出承璃。
第三部分
·用戶(hù)現(xiàn)在去請(qǐng)求onmpw2。
·onmpw2重定向到SSOsite蚌本,同樣設(shè)置ReturnUrl為剛開(kāi)始請(qǐng)求的onmpw2的頁(yè)面地址盔粹。
·瀏覽器接收到重定向的命令以后,因?yàn)楸镜卮嬖赟SOsite的cookie程癌,所以會(huì)cookie加到請(qǐng)求中發(fā)送給SSOsite舷嗡。
·SSOsite檢查接收到的請(qǐng)求中發(fā)現(xiàn)有cookie信息,首先會(huì)檢查該cookie信息是否過(guò)期嵌莉,如果沒(méi)有過(guò)期进萄,將會(huì)從cookie中提取出用戶(hù)token。然后帶著token重定向到最初的onmpw2中的地址锐峭。
·onmpw2發(fā)現(xiàn)請(qǐng)求中有用戶(hù)token中鼠,然后他會(huì)通過(guò)SSOsite的web/WCF服務(wù)驗(yàn)證token的合法性。驗(yàn)證成功以后只祠,將最初瀏覽器請(qǐng)求onmpw2的頁(yè)面發(fā)送給瀏覽器用以向用戶(hù)輸出兜蠕。
總結(jié)
哇哦扰肌,看起來(lái)有很多東西需要做抛寝。其實(shí)并沒(méi)有那么復(fù)雜。
起初,瀏覽器沒(méi)有所屬域?yàn)镾SOsite的cookie信息盗舰。因此無(wú)論是點(diǎn)擊任何站點(diǎn)的需要驗(yàn)證的界面都會(huì)跳轉(zhuǎn)到登錄頁(yè)(這個(gè)過(guò)程是由程序內(nèi)部重定向到SSOsite來(lái)檢查是否存在cookie的)晶府。一旦用戶(hù)登錄成功,所屬域?yàn)镾SOsite的钻趋,并且?guī)в械卿浻脩?hù)信息的cookie會(huì)被瀏覽器存儲(chǔ)在本地川陆。
然后,當(dāng)用戶(hù)再次訪問(wèn)需要驗(yàn)證的頁(yè)面的時(shí)候蛮位,同樣請(qǐng)求會(huì)在被重定向到SSOsite较沪,并且瀏覽器會(huì)帶上先前已經(jīng)保存的cookie信息。SSOsite檢索cookie失仁,從中提取出用戶(hù)token尸曼,并帶著這個(gè)token重定向到最初請(qǐng)求的站點(diǎn)頁(yè)面。然后該站點(diǎn)會(huì)通過(guò)web/WCF服務(wù)去驗(yàn)證token的合法性萄焦。然后將相應(yīng)的頁(yè)面發(fā)送給客戶(hù)端控轿。
一旦用戶(hù)通過(guò)該單點(diǎn)登錄模型登錄到站點(diǎn)上,請(qǐng)求任何需要驗(yàn)證的頁(yè)面都會(huì)內(nèi)部重定向到SSOsite驗(yàn)證cookie和提取用戶(hù)token拂封,然后將請(qǐng)求的頁(yè)面發(fā)送給瀏覽器輸出茬射。
2:
上面的兩個(gè)方案,重點(diǎn)都是帶著參數(shù)(可能是URL冒签,可能是token)重定向到另一個(gè)域名下在抛,
去請(qǐng)求這個(gè)域名下的應(yīng)用程序,然后應(yīng)用程序在新域名下生成COOKIE或者token镣衡,
然后再帶著Token(方案一之生成COOKIE霜定,不帶TOKEN)重定向回去。
下面我用PHP代碼模擬下
www.a.com????這個(gè)域名下有文件login.php 內(nèi)容如下
if(!array_key_exists('jump',$_GET)){setcookie("login",1);header('Location: http://www.b.com/login.php?jump');}
(圖1)
www.b.com????這個(gè)域名下也有個(gè)程序文件index.php(其實(shí)名字隨意)?內(nèi)容如下
if(array_key_exists('jump',$_GET)){setcookie("login",1);header('Location: http://www.a.com/login.php?jump');}
(圖2)
一開(kāi)始廊鸥,用戶(hù)在這兩個(gè)域名下望浩,未登錄的話都是沒(méi)COOKIE的。
此時(shí)用戶(hù)先訪問(wèn) a域名的login.php,登錄a成功之后執(zhí)行上面圖1的代碼惰说,
由于直接訪問(wèn)的www.a.com/login.php,
并沒(méi)有jump這個(gè)參數(shù)(圖2說(shuō)這個(gè)參數(shù)的作用)磨德,所以設(shè)置login成功,并用header重定向到了www.b.com/login且?guī)е鴍ump參數(shù)
當(dāng)b下的login.php收到j(luò)ump過(guò)來(lái)的參數(shù)時(shí)吆视,說(shuō)明是a登錄成功過(guò)來(lái)的典挑,那么b下的程序就直接設(shè)置cookie為 login=1
(此時(shí)因?yàn)橐呀?jīng)到了b域名下執(zhí)行的應(yīng)用程序,所以COOKIE的有效域?yàn)?a target="_blank" rel="nofollow">www.b.com)
之后再由b再重定向到 a域名啦吧,帶著jump參數(shù)您觉,這樣a就不會(huì)再跳轉(zhuǎn)到b下了。
此時(shí)授滓,www.a.com和www.b.com這兩個(gè)域名下琳水,都有了登錄狀態(tài)的cookie肆糕。
用戶(hù)無(wú)論去那個(gè)站,都不用再登錄了在孝。
方式一的原理即以上
方式二略
這兩個(gè)的重點(diǎn)诚啃,都是重定向到新域名之后生成新域名的cookie,然后再重定向回來(lái)