Cookie的secure屬性引起單點(diǎn)登錄中的循環(huán)登錄問(wèn)題
在實(shí)施單點(diǎn)登錄(SSO)時(shí),可能會(huì)遇到循環(huán)登錄問(wèn)題,導(dǎo)致用戶無(wú)法正常使用系統(tǒng)。本文首先介紹了單點(diǎn)登錄的基本概念和實(shí)現(xiàn)原理,然后詳細(xì)分析了循環(huán)登錄的產(chǎn)生原因,主要是由于Cookie的Secure屬性設(shè)置不當(dāng),在使用HTTP訪問(wèn)時(shí)Cookie無(wú)法被傳遞導(dǎo)致的。提出的解決方案包括使用HTTPS進(jìn)行訪問(wèn)或增加一個(gè)新的Cookie參數(shù)。此外,還探討了Cookie端口不隔離性的問(wèn)題,指出即使是不同端口的服務(wù)也會(huì)共享同一個(gè)Cookie,這增加了處理此類問(wèn)題的復(fù)雜性。整體來(lái)看,文章為開(kāi)發(fā)人員提供了處理和預(yù)防循環(huán)登錄問(wèn)題的有效策略。
一、單點(diǎn)登錄簡(jiǎn)單介紹
1.1 基本概念
一個(gè)公司內(nèi)部可能存在多個(gè)系統(tǒng),如果每一個(gè)人在使用不同系統(tǒng)的時(shí)候都需要重新登錄,那么會(huì)做大量系統(tǒng)登錄切換、耗費(fèi)比較多的精力去管理賬號(hào)和密碼,那么有沒(méi)有辦法在一個(gè)公司內(nèi)部的所有系統(tǒng)只需要一次登錄驗(yàn)證,后續(xù)使用其他系統(tǒng)的時(shí)候不用重復(fù)登錄就可以直接使用呢,這就是單點(diǎn)登錄要解決的問(wèn)題。
單點(diǎn)登錄英文全稱 Single Sign On(SSO),允許用戶一次登錄即可訪問(wèn)多個(gè)應(yīng)用程序或系統(tǒng),無(wú)需為每個(gè)應(yīng)用程序或系統(tǒng)分別輸入認(rèn)證憑據(jù),便可在其他所有系統(tǒng)中得到授權(quán),無(wú)需再次登錄。
1.2 基本實(shí)現(xiàn)原理
- 用戶登錄:用戶在任何一個(gè)應(yīng)用程序或系統(tǒng)中進(jìn)行身份驗(yàn)證,并提供他們的憑據(jù)。
- 認(rèn)證系統(tǒng)驗(yàn)證:該憑據(jù)被發(fā)送到認(rèn)證系統(tǒng)進(jìn)行驗(yàn)證。如果憑據(jù)有效,則認(rèn)證系統(tǒng)會(huì)為用戶生成數(shù)字簽名的令牌(如 Token 或 Ticket)。
- 令牌分發(fā):認(rèn)證系統(tǒng)將令牌返回給應(yīng)用程序或子系統(tǒng)。
- 應(yīng)用程序或系統(tǒng)授權(quán):應(yīng)用程序或系統(tǒng)使用令牌驗(yàn)證用戶的身份,并授權(quán)其訪問(wèn)相應(yīng)資源或服務(wù)。
- 跨域系統(tǒng)訪問(wèn):用戶可以通過(guò)同一令牌訪問(wèn)多個(gè)跨域應(yīng)用程序或系統(tǒng),而無(wú)需重復(fù)進(jìn)行身份驗(yàn)證。
二、循環(huán)登錄問(wèn)題
在某一天我們登錄一個(gè)內(nèi)部系統(tǒng)時(shí),突然出現(xiàn)了循環(huán)登錄問(wèn)題,前端頁(yè)面不斷刷新,提示“重定向次數(shù)過(guò)多問(wèn)題”。
打開(kāi)前端調(diào)試功能, 我們會(huì)發(fā)現(xiàn)確實(shí)存在大量重定向請(qǐng)求的問(wèn)題:
那么平時(shí)登錄沒(méi)問(wèn)題的系統(tǒng)為什么突然間就循環(huán)登錄呢?并在頁(yè)面上提示的解決方法“嘗試刪除您的 Cookie 操作”,按照這個(gè)操作以后,確實(shí)系統(tǒng)又可以跳轉(zhuǎn)到登錄頁(yè)面正常進(jìn)行登錄了,這又是什么原因?下面我們將逐一分析。
三、從一次正常登錄流程說(shuō)起
上述是一個(gè)通用的系統(tǒng)權(quán)限管控和單點(diǎn)系統(tǒng)認(rèn)證的標(biāo)準(zhǔn)流程:
- 用戶第一次訪問(wèn)時(shí),在瀏覽器輸入 https://aaa.x.y 回車
- 權(quán)限系統(tǒng)進(jìn)行攔截,判斷用戶是否登錄,這里主要是通過(guò)是否有登錄信息判斷,如果沒(méi)有登錄,權(quán)限系統(tǒng)會(huì)幫我們跳轉(zhuǎn)到單點(diǎn)登錄系統(tǒng),彈出用戶登錄頁(yè)。
- 用戶填寫用戶名、密碼,單點(diǎn)登錄系統(tǒng)進(jìn)行認(rèn)證后,將登錄狀態(tài)寫入 SSO 的 session。
- SSO 系統(tǒng)登錄完成后會(huì)給我們的系統(tǒng)生成一個(gè) Token ,然后跳轉(zhuǎn)到我們的系統(tǒng),同時(shí)將 Token 作為參數(shù)傳遞給我們的系統(tǒng)。
- 我們系統(tǒng)拿到 Token 后,從后臺(tái)向 SSO 發(fā)送請(qǐng)求,驗(yàn)證 Token 是否有效。
- 驗(yàn)證通過(guò)后,我們系統(tǒng)將記錄頂級(jí)域下的 Cookie 信息。
Connection: keep-alive Content-Length: 0 Date: Wed, 25 Oct 2023 08:29:43 GMT Location: http://aaa.x.y/console/login/auth?redirectUrl=http://aaa.x.y/ optrace: xx.xx.xx.xx:80/302 <- - Server: nginx Set-Cookie: token=fakdfajdfdjfdjkfaldfjk'afafjasfasfa; Max-Age=86400; Expires=Thu, 26-Oct-2023 08:29:43 GMT; Domain=x.y; Path=/; HttpOnly
一個(gè)公司內(nèi)部一般情況下只有一個(gè)域名,通過(guò)二級(jí)域名區(qū)分不同的系統(tǒng)。比如我們有個(gè)域名叫做:x.y ,同時(shí)有兩個(gè)業(yè)務(wù)系統(tǒng)分別為:app1.x.y 和 app2.x.y。SSO 登錄以后,可以將 Cookie 的域設(shè)置為頂域,即 x.y ,這樣所有子域的系統(tǒng)都可以訪問(wèn)到頂域的 Cookie,實(shí)現(xiàn)單點(diǎn)登錄功能。
四、循環(huán)登錄產(chǎn)生的根本原因
那么為什么會(huì)不斷循環(huán)登錄呢?
(1)從跳轉(zhuǎn)記錄來(lái)看,我們發(fā)現(xiàn)重新刷新頁(yè)面以后,重定向到了權(quán)限系統(tǒng),并且 Request Headers 中的 Cookie 信息沒(méi)有傳對(duì)應(yīng)的 Token 信息。
(2)跳轉(zhuǎn)到權(quán)限系統(tǒng)過(guò)后,再跳轉(zhuǎn)到本系統(tǒng)的時(shí)候,已經(jīng)獲取到了對(duì)應(yīng)的 Token 信息,但是在 Set-Cookie 信息的時(shí)候,出現(xiàn)了一個(gè)警告。
警告的具體內(nèi)容為:
大致意思是:這次執(zhí)行 Set-Cookie 操作被阻止了,原因是這個(gè) Cookie 不是通過(guò)安全的連接進(jìn)行傳輸?shù)?,我們這次訪問(wèn)確實(shí)使用了 HTTP 進(jìn)行,本應(yīng)該通過(guò)設(shè)置 Secure 屬性來(lái)覆蓋對(duì)應(yīng)的 Cookie。
這里的 Secure 屬性是 Cookie 的一個(gè)屬性,Secure 屬性是說(shuō)如果一個(gè) Cookie 被設(shè)置了 Secure = true,那么這個(gè) Cookie 只能用 HTTPS 協(xié)議發(fā)送給服務(wù)器,用 HTTP 協(xié)議是不發(fā)送的,而我們查看上面標(biāo)注位置的下一個(gè) Login 請(qǐng)求確實(shí)沒(méi)有傳 Cookie 信息,從而繼續(xù)進(jìn)行用戶是否登錄校驗(yàn),進(jìn)入死循環(huán)過(guò)程, 可以看下面的示意圖:
五、清除瀏覽器緩存的底層原理及解決方法
5.1 清除瀏覽器緩存的底層原理
我們可以看到循環(huán)登錄以后,會(huì)在瀏覽器頁(yè)面上提示 xxx.x.y 重定向次數(shù)過(guò)多,嘗試清除 Cookie 信息,那清除 Cookie 信息以后,是不是真的就可以解決這個(gè)問(wèn)題呢,我們嘗試著清除瀏覽器緩存,確實(shí)可以解決這個(gè)問(wèn)題,那清除瀏覽器緩存來(lái)解決循環(huán)登錄問(wèn)題的底層原理是什么呢,其實(shí)質(zhì)就是將 Cookie 刪除,其他域名設(shè)置 Cookie 上的 Secure 屬性也就一并刪除了,從而使用 HTTP 域名進(jìn)入重新登錄流程,可以正常設(shè)置 Cookie 信息。
5.2 其他解決辦法
方法一:使用 HTTPS 的方式進(jìn)行訪問(wèn)
現(xiàn)實(shí)使用中,我們無(wú)法控制其他 HTTPS 訪問(wèn)的具有相同頂級(jí)域名的服務(wù)不去設(shè)置 Cookie 的 Secure 屬性,因而我們?cè)诤竺媸褂玫倪^(guò)程中還是會(huì)遇到這個(gè)問(wèn)題,那么有沒(méi)有一種徹底的解決辦法能夠避免這個(gè)問(wèn)題再次出現(xiàn),我們前面已經(jīng)分析,之所以我們?cè)陂_(kāi)始使用 HTTP 能夠進(jìn)行正常訪問(wèn),然后突然間不能正常訪問(wèn)了,就是因?yàn)橐呀?jīng)被 HTTPS 設(shè)置了的 Cookie 信息是無(wú)法被 HTTP 重新設(shè)置的,從而拿不到 Cookie 信息。那么就出現(xiàn)了第一種解決辦法,使用 HTTPS 的方式進(jìn)行訪問(wèn),即使其他服務(wù)設(shè)置了 Cookie 的 Secure 屬性,用 HTTPS 仍然能夠成功設(shè)置 Cookie 和獲取 Cookie。
方法二:在 Cookie 信息中新設(shè)置一個(gè) newToken
以上從 HTTP 轉(zhuǎn)為 HTTPS 訪問(wèn)的方法在用戶主動(dòng)找我們反饋時(shí)是能夠告訴它切換為 HTTPS 訪問(wèn)的,但是如果對(duì)于一些沒(méi)有主動(dòng)找我們反饋的用戶,其實(shí)是無(wú)法解決,可能喪失這個(gè)用戶造成用戶流失的情況,那么我們?cè)谟脩舨贿M(jìn)行切換的情況下是否能夠解決這個(gè)問(wèn)題。
同一個(gè)公司內(nèi)部接入的權(quán)限系統(tǒng)是一種底層公共能力,為了保證單點(diǎn)登錄,其實(shí)用戶信息的讀取都是通過(guò)同一個(gè) Cookie 參數(shù)(比如叫 Token )讀取的,那么在其他域名設(shè)置了公共 Cookie 參數(shù)的 Secure 屬性而影響到 HTTP 登錄的時(shí)候,我們可以給服務(wù)新增加一個(gè) Cookie 參數(shù) newToken 去解決。
六、擴(kuò)展: Cookie 的端口不隔離性
本文所闡述的問(wèn)題,出現(xiàn)的背景是有兩個(gè)基本前提的:一是為了保證單點(diǎn)登錄,兩個(gè)域名屬于同一個(gè)頂級(jí)域名,權(quán)限系統(tǒng)中關(guān)于用戶信息的校驗(yàn)都是通過(guò)同一個(gè) Cookie 屬性去讀取的;第二個(gè)是 HTTPS 設(shè)置了頂級(jí)域名的 Cookie 信息的 Secure 屬性,然后使用 HTTP 訪問(wèn)會(huì)導(dǎo)致循環(huán)登錄。有些開(kāi)發(fā)者可能會(huì)有這樣一個(gè)疑問(wèn),那就是 HTTPS 我們一般開(kāi)通的端口是 443 , HTTP 我們一般開(kāi)通的端口是 8080 ,為啥不從端口上進(jìn)行區(qū)分同一個(gè) Cookie 屬性從而避免干擾呢?
這個(gè)在 Cookie 規(guī)范(RFC 6265)中有所描述,那就是 Cookie 不提供通過(guò)端口進(jìn)行隔離的,也就是說(shuō)如果一個(gè) Cookie 可以被一臺(tái)服務(wù)器上的運(yùn)行在某一個(gè)端口上的一個(gè)服務(wù)所讀取,那么也可以被這臺(tái)服務(wù)器上運(yùn)行在另外一個(gè)端口上的服務(wù)所讀??;如果一個(gè) Cookie 可以被一臺(tái)服務(wù)器上的運(yùn)行在某一個(gè)端口上的一個(gè)服務(wù)所寫入,那么也可以被這臺(tái)服務(wù)器上運(yùn)行在另外一個(gè)端口上的服務(wù)所寫入。
七、總結(jié)
單點(diǎn)登錄作為公共組件,在各個(gè)公司內(nèi)部被各個(gè)系統(tǒng)所廣泛使用,但是在使用過(guò)程中我們會(huì)遇到各種各樣的問(wèn)題,其中循環(huán)登錄問(wèn)題就是一個(gè)比較經(jīng)典的問(wèn)題。本文主要分析單點(diǎn)登錄和權(quán)限系統(tǒng)設(shè)計(jì)的基本原理,然后結(jié)合實(shí)際案例來(lái)分析循環(huán)登錄的原因,并給出具體的解決辦法。
本文從實(shí)際開(kāi)發(fā)過(guò)程中遇到的循環(huán)登錄問(wèn)題入手,分析了由于設(shè)置 Secure 屬性導(dǎo)致使用 HTTP 訪問(wèn)網(wǎng)頁(yè)無(wú)法保存 Cookie 信息從而導(dǎo)致循環(huán)登錄的根本原因,也給出了其他兩個(gè)解決此種問(wèn)題的方案,對(duì)于其他開(kāi)發(fā)人員解決權(quán)限系統(tǒng)循環(huán)登錄問(wèn)題具有一定的借鑒意義。
到此這篇關(guān)于Cookie的secure屬性引起單點(diǎn)登錄中的循環(huán)登錄問(wèn)題的文章就介紹到這了,更多相關(guān)單點(diǎn)登錄中的循環(huán)登錄內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
手機(jī)屏幕尺寸測(cè)試——手機(jī)的實(shí)際顯示頁(yè)面的寬度
本文主要通過(guò)測(cè)試,得出手機(jī)端網(wǎng)頁(yè)實(shí)際顯示的寬度,給開(kāi)發(fā)人員在做手機(jī)端開(kāi)發(fā)的時(shí)候做一些參考,希望能幫到大家。2016-04-04改進(jìn)網(wǎng)頁(yè)可讀性的7個(gè)方法
改進(jìn)網(wǎng)頁(yè)可讀性的7個(gè)方法...2006-11-11