這家集團(tuán)公司財(cái)大氣粗进宝,竟然自己建了一個(gè)數(shù)據(jù)中心, 放了數(shù)百臺(tái)機(jī)器枷恕, 部署了幾十個(gè)企業(yè)內(nèi)部系統(tǒng)即彪。
在無(wú)塵、恒溫活尊、恒濕的環(huán)境里,這些信息系統(tǒng)的日子過得非常愜意漏益。
他們只需要在白天應(yīng)對(duì)人類的HTTP 請(qǐng)求蛹锰,及時(shí)做出響應(yīng), 只要人類一下班绰疤, ?系統(tǒng)的負(fù)載就陡然下降铜犬,CPU內(nèi)存全部都空閑下來。 ?大家閑來無(wú)事轻庆, 熱熱鬧鬧的機(jī)房夜話就開始了癣猾。
希望大家一起來學(xué)習(xí)討論java方面的問題群號(hào):左邊六五八中間三六二 右邊六五八【JAVA學(xué)習(xí)交流2群】里面有很多學(xué)習(xí)資料以及大神討論。658362658
1第一夜
休假系統(tǒng)是用世界上最好的語(yǔ)言PHP做的余爆,他向來消息靈通纷宇,今天帶來了一個(gè)特別新聞:“ 號(hào)外號(hào)外, 聽說了嗎蛾方, 人類要搞SSO了像捶。”
Python 寫的報(bào)銷系統(tǒng)桩砰, ?C#寫的車輛管理系統(tǒng)早就看不慣PHP這種中英混雜的風(fēng)格了: “ 別拽了拓春,說中文!”
PHP休假系統(tǒng)很不屑: “就是單點(diǎn)登錄嘛亚隅,難道你們沒聽說過硼莽?”
C# 說: “不就是登錄嘛! 人類不是天天登錄系統(tǒng)煮纵? ?你看他們想調(diào)度車倆的時(shí)候懂鸵,就得登錄我的系統(tǒng)偏螺, 輸入用戶名和密碼, 我做驗(yàn)證矾瑰, 驗(yàn)證通過就建立session, ?然后把session id 通過cookie發(fā)送給人類的瀏覽器砖茸, 下次人類再訪問我的URL的時(shí)候, cookie就會(huì)發(fā)過來殴穴, 我就知道他已經(jīng)登錄過了凉夯。 “
C#很得意,向大家炫耀著登錄的原理采幌。
“對(duì)了劲够,告訴你們一個(gè)小秘密, 人類這些密碼太簡(jiǎn)單了休傍,不是123456, 就是abcd征绎。 ”
Python附和道: “ 是啊,人類太懶了磨取, 密碼超級(jí)簡(jiǎn)單人柿,聽說上一次有個(gè)家伙用領(lǐng)導(dǎo)賬號(hào)成功地登錄了系統(tǒng), 于是全集團(tuán)人員的工資都暴露了忙厌! ”
“那對(duì)于同一個(gè)人凫岖, 你這里的用戶名/密碼和小C#那里會(huì)一樣嗎?” ?PHP說
“這個(gè)逢净。哥放。。 很有可能不一樣爹土∩瘢”
PHP說: “對(duì)啊,這就是問題了胀茵, 這么多不同的用戶名社露,有的是郵箱地址,有的是手機(jī)號(hào)琼娘,有的是用戶名呵哨, 我們這里幾十個(gè)系統(tǒng),擱誰(shuí)都記不全啊! ?這就是他們?yōu)槭裁匆銌吸c(diǎn)登錄:在一個(gè)地方登錄一次轨奄, 就可以訪問我們這里所有的系統(tǒng)了”
C# 叫道: " 只需要登錄一次孟害? 聽起來很美好啊 ! ?讓我想想怎么實(shí)現(xiàn)挪拟, 對(duì)了挨务, 登錄就是cookie,那我們把cookie共享起來不就可以了? ?人類在報(bào)銷系統(tǒng)那里登錄后谎柄,再訪問我這個(gè)車輛管理系統(tǒng)丁侄, 把cookie發(fā)過來不就行了?"
眾人紛紛表示贊同朝巫。
PHP 心里再次鄙視了一下C# , 說: “NO , NO ,cookie是不能跨域的鸿摇, ?a.com 產(chǎn)生的cookie , 瀏覽器是不會(huì)發(fā)到b.com去的∨常”
有人在悄悄地google , ?PHP果然說得不錯(cuò)拙吉。
大家趕緊檢查了下自己的域名,有的叫 xxx.vaction.com, ?有的叫xxx.hr.com , ?看來共享cookie方案不管用揪荣。
PHP補(bǔ)充到: “也許人類能把我們統(tǒng)一到一級(jí)或二級(jí)域名下筷黔, 比如 xxx.company.com, ? 這樣cookie可以共享了! 但是我們后端沒有session 也不行啊仗颈, 你cookie發(fā)過來佛舱,我內(nèi)存中沒數(shù)據(jù),根本不知道你是否登錄過挨决, 怎么驗(yàn)證请祖?”
C#說: “session 也可以共享哦 , 你看我這個(gè)系統(tǒng)有兩個(gè)服務(wù)器脖祈,共享的是redis中的session肆捕, 將來我們這幾十個(gè)系統(tǒng)都共享同一個(gè)redis,想想都讓人激動(dòng)叭鱿!”
Python 說: “ 這么多系統(tǒng)掏秩, 架構(gòu)不同或舞,語(yǔ)言也不同, 共享session太麻煩了吧蒙幻? ”
C# 發(fā)愁地說: “那怎么辦映凳? ”
這時(shí)候旁邊傳來了一聲大吼: “你們?cè)谀抢锍吵呈裁矗献釉谏蓤?bào)表邮破,都沒法專心干活了诈豌!”
這是脾氣暴躁的COBOL在抱怨了, 千萬(wàn)不要惹這個(gè)老家伙抒和,于是大家紛紛噤聲矫渔, 老老實(shí)實(shí)地睡覺去了。
2第二夜
第二天晚上摧莽,COBOL程序終于歇著了庙洼, 大家繼續(xù)討論。
Python提了一個(gè)新點(diǎn)子:“要我說,我們別共享session了油够, 我們就用cookie, ?用戶在我這個(gè)報(bào)銷系統(tǒng)這里登錄了蚁袭, 我就在cookie中寫個(gè)token , ?用戶訪問別的系統(tǒng),就可以把token 帶過去石咬, 那個(gè)系統(tǒng)驗(yàn)證一下token 揩悄,如果沒問題,就認(rèn)為它已經(jīng)登錄了鬼悠∩拘裕”
“那token 得加密吧, 要不然誰(shuí)都可以偽造” ? C#安全意識(shí)挺強(qiáng)
“那是自然厦章, 聽說過json web token 沒有镇匀? 我們每個(gè)系統(tǒng)在生成token 的時(shí)候,都要對(duì)數(shù)據(jù)做個(gè)簽名袜啃,防止別人篡改汗侵, 下面就是我生產(chǎn)的token , ?其中有header 信息和userID, ?你看我用Hash算法和密鑰生產(chǎn)了一個(gè)簽名群发。 這個(gè)簽名啊也是token數(shù)據(jù)的一部分晰韵, 到時(shí)候也會(huì)發(fā)到你的系統(tǒng)去” ?Python 說
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(計(jì)算簽名的過程)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (放置到cookie中的token)
C#說: “明白了, 我收到了token 熟妓,就用同樣的算法再計(jì)算簽名雪猪,然后和你計(jì)算的相比, 如果相等起愈,證明他登錄過只恨,我可以直接取出userID使用了, ?如果不相等抬虽, 說明有人篡改官觅, 我就關(guān)門放狗, 把他暴揍一頓阐污⌒莸樱”
Ruby ?插嘴說: “這個(gè)辦法不錯(cuò),輕量級(jí)笛辟,我喜歡功氨! ?只是這個(gè)算法和密鑰大家都得一致才行。 密鑰的分發(fā)也是個(gè)問題手幢〗萜啵”
PHP聽了半天, 發(fā)現(xiàn)了一個(gè)漏洞:“你這個(gè)token中放了一個(gè)userID, 可是我們每個(gè)系統(tǒng)的userID都不一樣啊围来, 你的userID 我拿過來沒有任何用處纵势, 怎么辦踱阿?”
這的確是個(gè)致命的問題!每個(gè)系統(tǒng)中都有一套自己獨(dú)特的user id ,互不共享钦铁,這樣以來之前討論的什么共享session, 共享cookie ,都很難實(shí)現(xiàn)了 !
一陣沉默软舌, 看來沒救了。
夜已深牛曹,大家討論得有點(diǎn)累了佛点,紛紛睡去。
3第三夜
第三天黎比,機(jī)房夜話繼續(xù)超营, 但還是沒有解決方案。氣氛有點(diǎn)小尷尬阅虫。
老成持重的Java咳嗽了幾聲演闭,示意要發(fā)言了。
“你們知道嗎颓帝, 我們是一個(gè)企業(yè)內(nèi)部系統(tǒng)米碰,人類搞SSO就是想消除這多個(gè)賬號(hào)的問題,將來每個(gè)系統(tǒng)都不需要維護(hù)自己的用戶系統(tǒng)购城, 他們會(huì)建立一個(gè)統(tǒng)一的認(rèn)證中心吕座,所有的用戶注冊(cè)和認(rèn)證都在那里做”癜澹”
“這么做行得通嗎吴趴,認(rèn)證中心怎么通知我們說用戶已經(jīng)認(rèn)證了?” ?C#問道
“這個(gè)過程稍微有點(diǎn)復(fù)雜” 侮攀, Java 對(duì)C# 說锣枝, “舉個(gè)例子來解釋下, 比如用戶通過瀏覽器先訪問你這個(gè)系統(tǒng)www.a.com/pageA兰英, 這個(gè)pageA是個(gè)需要登錄才能訪問的頁(yè)面撇叁,你發(fā)現(xiàn)用戶沒有登錄, 這時(shí)候你需要做一件額外的操作箭昵,就是重定向到認(rèn)證中心税朴,www.sso.com/login?redirect=www.a.com/pageA”
C#說: “為什么后面要跟一個(gè)redirect的url呢回季? 奧家制,明白了, 將來認(rèn)證通過后泡一,還要重定向到我這里來颤殴。”
“沒錯(cuò)鼻忠, 瀏覽器會(huì)用這個(gè)www.sso.com/login?redirect=www.a.com/pageA去訪問認(rèn)證中心涵但, 認(rèn)證中心一看, 沒登錄過, 認(rèn)證中心就讓用戶去登錄矮瘟, 登錄成功以后瞳脓, 認(rèn)證中心要做幾件重要的事情 :
1. 建立一個(gè)session。
2. 創(chuàng)建一個(gè)ticket (可以認(rèn)為是個(gè)隨機(jī)字符串)
3. ?然后再重定向到你那里澈侠, url 中帶著ticket : www.a.com/pageA?ticket=T123 ? 與此同時(shí)cookie也會(huì)發(fā)給瀏覽器劫侧,比如:Set cookie : ssoid=1234, sso.com”
“可是這個(gè)cookie對(duì)我一點(diǎn)用處都沒有啊,跨域不能訪問啊哨啃∩斩埃”
“人家網(wǎng)站sso.com的cookie對(duì)你肯定沒用了, 瀏覽器會(huì)保存下來拳球。 但是注意那個(gè)ticket ” ?Java 提醒道审姓, “這個(gè)東西是個(gè)重要的標(biāo)識(shí),你拿到以后需要再次向認(rèn)證中心做驗(yàn)證祝峻∧拢”
“明白,是為了防止不壞好意的人偽造”
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(點(diǎn)擊看大圖哦)
“你拿著token ,去問下認(rèn)證中心呼猪, 這是您發(fā)的token 嗎画畅, 認(rèn)證中心說沒錯(cuò),是我發(fā)的宋距,那你就可以認(rèn)為用戶在認(rèn)證中心登錄過了”
“那我該干什么事情呢轴踱? ”
“瀏覽器向你發(fā)出的請(qǐng)求不是www.a.com/pageA?ticket=T123 嗎, 這時(shí)候你既然認(rèn)為用戶已經(jīng)登錄過了谚赎,那就給他建立session, 返回pageA這個(gè)資源啊”
“嗯淫僻, 我還需要給瀏覽器發(fā)一個(gè)cookie, 對(duì)吧, 這是屬于我的cookie : Set cookie : sessionid=xxxx, a.com ” ?C# 說道
"孺子可教壶唤, 注意雳灵,這時(shí)候?yàn)g覽器實(shí)際上有兩個(gè)cookie,一個(gè)是你發(fā)的,另外一個(gè)是認(rèn)證中心發(fā)的闸盔。"
“如果用戶再次訪問我另外一個(gè)受保護(hù)的頁(yè)面悯辙,www.a.com/pageA1, 該怎么辦迎吵? 難道還要去認(rèn)證中心登錄 ” ?C#繼續(xù)問
“那當(dāng)然不用了躲撰,你給瀏覽器發(fā)過你自己的cookie , 到時(shí)候?yàn)g覽器自然會(huì)帶過來,你就知道它登錄過了击费。 ”
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(點(diǎn)擊看大圖哦)
“原來如此拢蛋, 好麻煩啊” ?C#感慨道。
Python 插了一句: “如果用戶訪問C#的系統(tǒng)(www.a.com/pageA)時(shí)已經(jīng)通過認(rèn)證中心登錄了蔫巩, 然后再訪問我www.b.com/pageB, 會(huì)發(fā)生什么狀況呢谆棱?”
Java 說:“很簡(jiǎn)單快压, 和訪問www.a.com/pageA非常類似,唯一的不同就是不需要用戶登錄了垃瞧,因?yàn)闉g覽器已經(jīng)有了認(rèn)證中心的cookie蔫劣, 直接發(fā)給www.sso.com就可以了”
說著, Java 又畫了兩張圖个从。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (點(diǎn)擊看大圖哦)
同樣拦宣,認(rèn)證中心會(huì)返回token , www.b.com 需要做驗(yàn)證
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (點(diǎn)擊看大圖哦)
PHP 一直在努力的聽,他說: “其實(shí)本質(zhì)上就一個(gè)認(rèn)證中心的cookie ,加上多個(gè)子系統(tǒng)的cookie 而已信姓!”
Java 撇了一眼PHP : “總結(jié)的很精辟鸵隧!”
C#發(fā)現(xiàn)了一點(diǎn)新東西: “在認(rèn)證中心,為什么要去做一個(gè)系統(tǒng)注冊(cè)的操作呢意推?豆瘫, 我看到注冊(cè)了系統(tǒng)A,還有系統(tǒng)B”
"SSO 是單點(diǎn)登錄,是不是還要有單點(diǎn)退出啊菊值, 用戶在一個(gè)系統(tǒng)退出了外驱,認(rèn)證中心需要把自己的會(huì)話和cookie干掉,然后還要去通知各個(gè)系統(tǒng)腻窒, 讓他們把自己的會(huì)話統(tǒng)統(tǒng)干掉昵宇,這樣才能在所有的系統(tǒng)都實(shí)現(xiàn)真正地退出啊。" Java回答儿子。
大家琢磨了一會(huì)兒瓦哎,很快就喧囂起來:
“太麻煩了”
“我們的代碼還得改動(dòng)不少呢”
“重定向太多了, 把我都搞暈了”
“我覺得人類不會(huì)這么搞柔逼!”
......
Java 說“別小看它蓖谢, 這個(gè)點(diǎn)子是耶魯大學(xué)提出的纳鼎,叫做CAS(Central Authentication Server ) , ?是一個(gè)很著名的SSO解決方案, 弄不好人類就會(huì)采用行楞。 ?你們吶级乍,還是好好學(xué)學(xué)吧骑祟』猎瑁”
希望大家一起來學(xué)習(xí)討論java方面的問題群號(hào):左邊六五八中間三六二 右邊六五八【JAVA學(xué)習(xí)交流2群】里面有很多學(xué)習(xí)資料以及大神討論狐肢。658362658