[轉] SSO單點登陸原理和流程分析

WEB的登陸那些事####

說道帳戶登陸和註冊,其實咱們天天都在親身感覺着,像微博、知乎還有簡書等等。咱們老是須要按期的去從新登陸一下,對於這種認證機制,咱們都能說出來兩個名詞,Cookie、Session。的確沒錯,Cookie和Session是實現這一切的核心。前端

爲何會有Cookie和Session?區別是什麼?
引入這兩個概念的根本緣由是由於Http協議是無狀態的,也就是說它不能創建起屢次請求之間的關係。因此須要引入一個能有瀏覽器或服務器保存的一個上下文狀態,也就是Cookie和Session。說到底Session的實現是依賴於Cookie的,由於Cookie是真正的由瀏覽器保存的狀態,Session是利用了JSessionID。在我看來其實二者有差別,可是根本的依賴是同樣的。Cookie也是有生命週期的,像Session級別或者有必定「壽命」的Cookie。一切是由瀏覽器去維護的。java

常見的跨域登陸問題####

以前樓主主要是作帳戶和Passport這方面的工做,其實在跨域這也是遇見了一些問題。json

對於同一個根域下的登陸問題#####

若是咱們的站點有不止一個業務,那麼他們可能部署在不一樣的機器上,也每每須要不一樣的域名進行區分。可是全部的業務又都是依賴於一套帳戶體系,那麼咱們這時候須要經過一次登陸解決全部站點的登陸問題,那麼咱們這個時候可使用一個最笨的方法:那就是一次登陸成功,將Cookie寫到根域下,那麼這樣全部的站點就能實現,同一個根域下的Cookie共享,天然實現了」單點登陸「。後端

對於多個根域下的登陸問題#####

若是是多個根域名,那麼這種狀況下上面的機制就不能實現「單點登陸」了。由於之因此上面能夠實現「單點登陸」的效果。是由於瀏覽器和Http協議的支持。可是對於跨根域的站點之間進行Cookie的共享是比較複雜的。跨域

方法1:登陸成功以後將Cookie回寫到多個域名下。瀏覽器

這種辦法可能十分簡單,你能夠經過後端的response寫,也能夠用前端js去寫,可是必須有對全部須要「單點登陸」的站點進行逐一的寫入。用腳想這種辦法也是行不通的,由於你須要維護一個站點的列表,維護工做十分複雜,同時對於增長站點也會特別痛苦。對於Cookie的銷燬也是十分複雜的,由於仍是要對全部域名下的Cookie進行刪除。也就是說將原來須要作的工做增長了n倍。對於小型站點這種辦法是可取的。安全

方法2:jsonp服務器

搞過前端的可能都知道用jsonp能夠作跨域的請求,而咱們解決的就是多個域下的統一登陸的問題,好像很瓜熟蒂落的樣子。可是,登陸是Server端作的吧?咱們在Client端作跨域的處理,這怎麼看也不是很合理。同時這種辦法須要很大的維護成本,每一次請求都要去固定的域下取相應的Cookie以後再作請求。想一想維護有頭疼。ide

方法3 :引入一箇中間態的Serverjsonp

這種辦法算是一個簡化版的SSO,實現思想也十分的「狡猾」。可是對於小網站作跨域登陸的處理卻十分的有用,具體思路以下:

首先,咱們有兩個域名要實現單點登陸,同時咱們須要一箇中間的Server。

  1. 咱們有一個系統域名爲xulingbo.net,當咱們登陸的時候訪問xulingbo.net/wp-login進行登陸,登陸成功以後將Cookie回寫到xulingbo這個域名下。
  2. 咱們還有一個系統域名爲javaWeb.com,當咱們訪問inside-javaWeb的時候,咱們沒有Cookie,那麼請求跳轉到中間系統jump。此時須要將當前域名帶到參數中便於jump校驗。這個jump系統是在xulingbo域下的即:jump.xulingbo.net。這時候就能拿到以前寫在xulingbo域下的Cookie。
  3. jump系統在收到了xulingbo域下的Cookie以後,取出xulingbo域下的Cookie,並redirect請求jump.inside-javaWeb.net,這個接口也是在jump系統中,請求後jump系統將Cookie回寫到inside-javaWeb域名下,這樣就實現了簡易的單點登陸。以下圖所示:
 
Paste_Image.png

可是這種方式不是很靈活,對於數據傳輸的安全性沒有保障,而且在銷燬Cookie的時候無能爲力,只能所有遍歷的銷燬。

方法4:基於CAS的SSO系統

CAS可不是java中的Compare-And-Swap,它是一個開源的單點登陸系統(SSO)。實現的機制不算複雜可是思想十分靈巧。用CAS也能夠快速實現單點登陸。盜圖一張說明sso單個域的登陸和驗證流程:

 
Paste_Image.png

CAS主要分爲CAS Client 和CAS Server ,其中Client主要是內嵌在須要SSO登陸站點的攔截器或過濾器上。

  1. 首先瀏覽器向站點1發起請求。
  2. 站點1發現當前請求沒有合法的Cookie,那麼重定向到CAS Server上,也就是SSO Server。
  3. CAS Server展現登陸界面,要求用戶登陸。
  4. 用戶登陸後,會寫CAS Server的Cookie到瀏覽器,同時生產ticket,利用一個302跳轉到CASClient。這樣能保證用戶無感知。
  5. CAS Client利用生成的ticket發送到CAS Server進行驗證,驗證經過後,站點1生成本身的Cookie並回寫到用戶瀏覽器,而後進行登陸成功的跳轉。

這樣就能保證當前瀏覽器在站點1的域名下,有站點1的Cookie,同時當前瀏覽器也有CAS Server的Cookie。

接下來看下站點2的登陸:

 
Paste_Image.png

站點2,在進行登陸時和站點1初次登陸流程一致,可是在訪問CAS Server的時候,因爲當前瀏覽器已經有了CAS Server的Cookie,那麼直接校驗經過返回ticket。
ticket經過302跳轉跳轉到CAS Client上,以後的流程就和站點1是同樣的了。若是此時認證失敗,那麼須要從新走一次登陸的過程。

其實感受很麻煩,可是流程卻十分的簡單,主要是使用CAS Server的Cookie作校驗,同時各自系統維護本身的Cookie。

注意的問題:

  1. CAS Server的Cookie劫持問題,若是CAS Server的Cookie被劫持掉,那麼就至關於拿到了一切,因此必需要用HTTPS實現這個過程。
  2. ticket的使用,ticket只能被使用一次,一次校驗後當即失效。同時須要有時效性,通常5分鐘。最後ticket生成規則要隨機,不能被碰撞出來。
  3. 對於各自系統本身的Session,也能夠依賴於SSO,這樣就能保證全部的Session規則一致,便於集中控制。

其實SSO的實現很靈活,CAS只是說了一個原理,至於具體怎麼實現,須要平衡安全性、易用性等諸多因素,因此也沒有一個固定的實現方案。

上面就是所有我知曉的SSO的實現了,由於以前一直在作相關的東西,這個過程當中也作了不少的掙扎和思考,整理出來,幫助全部正在作的童鞋們。若是有什麼錯誤還請指出,有什麼更好的方法也但願能分享給我。感謝。

做者:一隻小哈連接:https://www.jianshu.com/p/c35344d15278來源:簡書著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
相關文章
相關標籤/搜索