1. 程式人生 > >單點登入原理與簡單實現(轉) 單點登入原理與簡單實現

單點登入原理與簡單實現(轉) 單點登入原理與簡單實現

單點登入原理與簡單實現

 

(2017-09-22更新)GitHub:https://github.com/sheefee/simple-sso

一、單系統登入機制

1、http無狀態協議

  web應用採用browser/server架構,http作為通訊協議。http是無狀態協議,瀏覽器的每一次請求,伺服器會獨立處理,不與之前或之後的請求產生關聯,這個過程用下圖說明,三次請求/響應對之間沒有任何聯絡

3c91a3bf-25d8-4b1f-8e4a-68535c51aaa8

  但這也同時意味著,任何使用者都能通過瀏覽器訪問伺服器資源,如果想保護伺服器的某些資源,必須限制瀏覽器請求;要限制瀏覽器請求,必須鑑別瀏覽器請求,響應合法請求,忽略非法請求;要鑑別瀏覽器請求,必須清楚瀏覽器請求狀態。既然http協議無狀態,那就讓伺服器和瀏覽器共同維護一個狀態吧!這就是會話機制

2、會話機制

  瀏覽器第一次請求伺服器,伺服器建立一個會話,並將會話的id作為響應的一部分發送給瀏覽器,瀏覽器儲存會話id,並在後續第二次和第三次請求中帶上會話id,伺服器取得請求中的會話id就知道是不是同一個使用者了,這個過程用下圖說明,後續請求與第一次請求產生了關聯

8a9fb230-d506-4b19-b821-4001c68c4588

  伺服器在記憶體中儲存會話物件,瀏覽器怎麼儲存會話id呢?你可能會想到兩種方式

  1. 請求引數
  2. cookie

  將會話id作為每一個請求的引數,伺服器接收請求自然能解析引數獲得會話id,並藉此判斷是否來自同一會話,很明顯,這種方式不靠譜。那就瀏覽器自己來維護這個會話id吧,每次傳送http請求時瀏覽器自動傳送會話id,cookie機制正好用來做這件事。cookie是瀏覽器用來儲存少量資料的一種機制,資料以”key/value“形式儲存,瀏覽器傳送http請求時自動附帶cookie資訊

  tomcat會話機制當然也實現了cookie,訪問tomcat伺服器時,瀏覽器中可以看到一個名為“JSESSIONID”的cookie,這就是tomcat會話機制維護的會話id,使用了cookie的請求響應過程如下圖

518293d9-64b2-459c-9d45-9f353c757d1f

3、登入狀態

  有了會話機制,登入狀態就好明白了,我們假設瀏覽器第一次請求伺服器需要輸入使用者名稱與密碼驗證身份,伺服器拿到使用者名稱密碼去資料庫比對,正確的話說明當前持有這個會話的使用者是合法使用者,應該將這個會話標記為“已授權”或者“已登入”等等之類的狀態,既然是會話的狀態,自然要儲存在會話物件中,tomcat在會話物件中設定登入狀態如下

1 2 HttpSession session = request.getSession(); session.setAttribute( "isLogin" true );

  使用者再次訪問時,tomcat在會話物件中檢視登入狀態

1 2 HttpSession session = request.getSession(); session.getAttribute( "isLogin" );

  實現了登入狀態的瀏覽器請求伺服器模型如下圖描述

70e396fa-1bf2-42f8-a504-ce20306e31fa

  每次請求受保護資源時都會檢查會話物件中的登入狀態,只有 isLogin=true 的會話才能訪問,登入機制因此而實現。

二、多系統的複雜性

  web系統早已從久遠的單系統發展成為如今由多系統組成的應用群,面對如此眾多的系統,使用者難道要一個一個登入、然後一個一個登出嗎?就像下圖描述的這樣

6dfbb0b1-46c0-4945-a3bf-5f060fa80710

  web系統由單系統發展成多系統組成的應用群,複雜性應該由系統內部承擔,而不是使用者。無論web系統內部多麼複雜,對使用者而言,都是一個統一的整體,也就是說,使用者訪問web系統的整個應用群與訪問單個系統一樣,登入/登出只要一次就夠了

9fe14ab3-4254-447b-b850-0436e628c254

  雖然單系統的登入解決方案很完美,但對於多系統應用群已經不再適用了,為什麼呢?

  單系統登入解決方案的核心是cookie,cookie攜帶會話id在瀏覽器與伺服器之間維護會話狀態。但cookie是有限制的,這個限制就是cookie的域(通常對應網站的域名),瀏覽器傳送http請求時會自動攜帶與該域匹配的cookie,而不是所有cookie

4d58ccfa-0114-486d-bec2-c28f2f9eb513

  既然這樣,為什麼不將web應用群中所有子系統的域名統一在一個頂級域名下,例如“*.baidu.com”,然後將它們的cookie域設定為“baidu.com”,這種做法理論上是可以的,甚至早期很多多系統登入就採用這種同域名共享cookie的方式。

  然而,可行並不代表好,共享cookie的方式存在眾多侷限。首先,應用群域名得統一;其次,應用群各系統使用的技術(至少是web伺服器)要相同,不然cookie的key值(tomcat為JSESSIONID)不同,無法維持會話,共享cookie的方式是無法實現跨語言技術平臺登入的,比如java、php、.net系統之間;第三,cookie本身不安全。

  因此,我們需要一種全新的登入方式來實現多系統應用群的登入,這就是單點登入

三、單點登入

  什麼是單點登入?單點登入全稱Single Sign On(以下簡稱SSO),是指在多系統應用群中登入一個系統,便可在其他所有系統中得到授權而無需再次登入,包括單點登入與單點登出兩部分

1、登入

  相比於單系統登入,sso需要一個獨立的認證中心,只有認證中心能接受使用者的使用者名稱密碼等安全資訊,其他系統不提供登入入口,只接受認證中心的間接授權。間接授權通過令牌實現,sso認證中心驗證使用者的使用者名稱密碼沒問題,建立授權令牌,在接下來的跳轉過程中,授權令牌作為引數傳送給各個子系統,子系統拿到令牌,即得到了授權,可以藉此建立區域性會話,區域性會話登入方式與單系統的登入方式相同。這個過程,也就是單點登入的原理,用下圖說明

  下面對上圖簡要描述

  1. 使用者訪問系統1的受保護資源,系統1發現使用者未登入,跳轉至sso認證中心,並將自己的地址作為引數
  2. sso認證中心發現使用者未登入,將使用者引導至登入頁面
  3. 使用者輸入使用者名稱密碼提交登入申請
  4. sso認證中心校驗使用者資訊,建立使用者與sso認證中心之間的會話,稱為全域性會話,同時建立授權令牌
  5. sso認證中心帶著令牌跳轉會最初的請求地址(系統1)
  6. 系統1拿到令牌,去sso認證中心校驗令牌是否有效
  7. sso認證中心校驗令牌,返回有效,註冊系統1
  8. 系統1使用該令牌建立與使用者的會話,稱為區域性會話,返回受保護資源
  9. 使用者訪問系統2的受保護資源
  10. 系統2發現使用者未登入,跳轉至sso認證中心,並將自己的地址作為引數
  11. sso認證中心發現使用者已登入,跳轉回系統2的地址,並附上令牌
  12. 系統2拿到令牌,去sso認證中心校驗令牌是否有效
  13. sso認證中心校驗令牌,返回有效,註冊系統2
  14. 系統2使用該令牌建立與使用者的區域性會話,返回受保護資源

  使用者登入成功之後,會與sso認證中心及各個子系統建立會話,使用者與sso認證中心建立的會話稱為全域性會話,使用者與各個子系統建立的會話稱為區域性會話,區域性會話建立之後,使用者訪問子系統受保護資源將不再通過sso認證中心,全域性會話與區域性會話有如下約束關係

  1. 區域性會話存在,全域性會話一定存在
  2. 全域性會話存在,區域性會話不一定存在
  3. 全域性會話銷燬,區域性會話必須銷燬

  你可以通過部落格園、百度、csdn、淘寶等網站的登入過程加深對單點登入的理解,注意觀察登入過程中的跳轉url與引數

2、登出

  單點登入自然也要單點登出,在一個子系統中登出,所有子系統的會話都將被銷燬,用下面的圖來說明

3b139d2e-0b83-4a69-b4f2-316adb8997ce

  sso認證中心一直監聽全域性會話的狀態,一旦全域性會話銷燬,監聽器將通知所有註冊系統執行登出操作

  下面對上圖簡要說明

  1. 使用者向系統1發起登出請求
  2. 系統1根據使用者與系統1建立的會話id拿到令牌,向sso認證中心發起登出請求
  3. sso認證中心校驗令牌有效,銷燬全域性會話,同時取出所有用此令牌註冊的系統地址
  4. sso認證中心向所有註冊系統發起登出請求
  5. 各註冊系統接收sso認證中心的登出請求,銷燬區域性會話
  6. sso認證中心引導使用者至登入頁面

四、部署圖

  單點登入涉及sso認證中心與眾子系統,子系統與sso認證中心需要通訊以交換令牌、校驗令牌及發起登出請求,因而子系統必須整合sso的客戶端,sso認證中心則是sso服務端,整個單點登入過程實質是sso客戶端與服務端通訊的過程,用下圖描述

fb29685c-487c-42b9-9ceb-6c7ee29e98c9

  sso認證中心與sso客戶端通訊方式有多種,這裡以簡單好用的httpClient為例,web service、rpc、restful api都可以

五、實現

  只是簡要介紹下基於java的實現過程,不提供完整原始碼,明白了原理,我相信你們可以自己實現。sso採用客戶端/服務端架構,我們先看sso-client與sso-server要實現的功能(下面:sso認證中心=sso-server)

  sso-client

  1. 攔截子系統未登入使用者請求,跳轉至sso認證中心
  2. 接收並存儲sso認證中心傳送的令牌
  3. 與sso-server通訊,校驗令牌的有效性
  4. 建立區域性會話
  5. 攔截使用者登出請求,向sso認證中心傳送登出請求
  6. 接收sso認證中心發出的登出請求,銷燬區域性會話

  sso-server

  1. 驗證使用者的登入資訊
  2. 建立全域性會話
  3. 建立授權令牌
  4. 與sso-client通訊傳送令牌
  5. 校驗sso-client令牌有效性
  6. 系統註冊
  7. 接收sso-client登出請求,登出所有會話

  接下來,我們按照原理來一步步實現sso吧!

1、sso-client攔截未登入請求

  java攔截請求的方式有servlet、filter、listener三種方式,我們採用filter。在sso-client中新建LoginFilter.java類並實現Filter介面,在doFilter()方法中加入對未登入使用者的攔截

1 2 3 4 5 6 7 8 9 10 11 12 public  void  doFilter(ServletRequest request, ServletResponse response, FilterChain chain)  throws  IOException, ServletException {      HttpServletRequest req = (HttpServletRequest) request;      HttpServletResponse res = (HttpServletResponse) response;      HttpSession session = req.getSession();            if  (session.getAttribute( "isLogin" )) {          chain.doFilter(request, response);          return ;      }      //跳轉至sso認證中心      res.sendRedirect( "sso-server-url-with-system-url" ); }

2、sso-server攔截未登入請求

  攔截從sso-client跳轉至sso認證中心的未登入請求,跳轉至登入頁面,這個過程與sso-client完全一樣

3、sso-server驗證使用者登入資訊

  使用者在登入頁面輸入使用者名稱密碼,請求登入,sso認證中心校驗使用者資訊,校驗成功,將會話狀態標記為“已登入”

1 2 3 4 5 6 @RequestMapping ( "/login" ) public  String login(String username, String password, HttpServletRequest req) {      this .checkLoginInfo(username, password);      req.getSession().setAttribute( "isLogin" true );      return  "success" ; }

4、sso-server建立授權令牌

  授權令牌是一串隨機字元,以什麼樣的方式生成都沒有關係,只要不重複、不易偽造即可,下面是一個例子

1 String token = UUID.randomUUID().toString();

5、sso-client取得令牌並校驗

  sso認證中心登入後,跳轉回子系統並附上令牌,子系統(sso-client)取得令牌,然後去sso認證中心校驗,在LoginFilter.java的doFilter()中新增幾行

1 2 3 4 5 6 7 8 9 10 11 // 請求附帶token引數 String token = req.getParameter( "token" ); if  (token !=  null ) {      // 去sso認證中心校驗token      boolean  verifyResult =  this .verify( "sso-server-verify-url" , token);      if  (!verifyResult) {          res.sendRedirect( "sso-server-url" );          return ;      }      chain.doFilter(request, response); }

  verify()方法使用httpClient實現,這裡僅簡略介紹,httpClient詳細使用方法請參考官方文件

1 2 HttpPost httpPost =  new  HttpPost( "sso-server-verify-url-with-token" ); HttpResponse httpResponse = httpClient.execute(httpPost);

6、sso-server接收並處理校驗令牌請求

  使用者在sso認證中心登入成功後,sso-server建立授權令牌並存儲該令牌,所以,sso-server對令牌的校驗就是去查詢這個令牌是否存在以及是否過期,令牌校驗成功後sso-server將傳送校驗請求的系統註冊到sso認證中心(就是儲存起來的意思)

  令牌與註冊系統地址通常儲存在key-value資料庫(如redis)中,redis可以為key設定有效時間也就是令牌的有效期。redis執行在記憶體中,速度非常快,正好sso-server不需要持久化任何資料。

  令牌與註冊系統地址可以用下圖描述的結構儲存在redis中,可能你會問,為什麼要儲存這些系統的地址?如果不儲存,登出的時候就麻煩了,使用者向sso認證中心提交登出請求,sso認證中心登出全域性會話,但不知道哪些系統用此全域性會話建立了自己的區域性會話,也不知道要向哪些子系統傳送登出請求登出區域性會話

3b221593-f9c4-45af-a567-4937786993e8

7、sso-client校驗令牌成功建立區域性會話

  令牌校驗成功後,sso-client將當前區域性會話標記為“已登入”,修改LoginFilter.java,新增幾行

1 2 3 if  (verifyResult) {      session.setAttribute( "isLogin" true ); }

  sso-client還需將當前會話id與令牌繫結,表示這個會話的登入狀態與令牌相關,此關係可以用java的hashmap儲存,儲存的資料用來處理sso認證中心發來的登出請求

8、登出過程

  使用者向子系統傳送帶有“logout”引數的請求(登出請求),sso-client攔截器攔截該請求,向sso認證中心發起登出請求

1 2 3 4 String logout = req.getParameter( "logout" ); if  (logout !=  null ) {      this .ssoServer.logout(token); }

  sso認證中心也用同樣的方式識別出sso-client的請求是登出請求(帶有“logout”引數),sso認證中心登出全域性會話

1 2 3 4 5 6 7 8 @RequestMapping ( "/logout" ) public  String logout(HttpServletRequest req) {      HttpSession session = req.getSession();      if  (session !=  null ) {          session.invalidate(); //觸發LogoutListener      }      return  "redirect:/" ; }

  sso認證中心有一個全域性會話的監聽器,一旦全域性會話登出,將通知所有註冊系統登出

1 2 3 4 5 6 7 8 public  class  LogoutListener  implements  HttpSessionListener {      @Override      public  void  sessionCreated(HttpSessionEvent event) {}      @Override      public  void  sessionDestroyed(HttpSessionEvent event) {          //通過httpClient向所有註冊系統傳送登出請求      } }

(完)

作者:凌承一 
出處:http://www.cnblogs.com/ywlaker/ 
宣告:本文版權歸作者和部落格園共有,歡迎轉載,但轉載必須保留此段宣告,並在文章頁面明顯位置給出原文連結,否則作者將保留追究法律責任的權利。

      好文要頂  關注我  收藏該文    ywlaker
關注 - 1
粉絲 - 179     +加關注 290 6       » 下一篇: java日誌框架log4j詳細配置及與slf4j聯合使用教程 posted @  2016-11-29 15:53 ywlaker 閱讀(349141) 評論(255) 編輯 收藏

(2017-09-22更新)GitHub:https://github.com/sheefee/simple-sso

一、單系統登入機制

1、http無狀態協議

  web應用採用browser/server架構,http作為通訊協議。http是無狀態協議,瀏覽器的每一次請求,伺服器會獨立處理,不與之前或之後的請求產生關聯,這個過程用下圖說明,三次請求/響應對之間沒有任何聯絡

3c91a3bf-25d8-4b1f-8e4a-68535c51aaa8

  但這也同時意味著,任何使用者都能通過瀏覽器訪問伺服器資源,如果想保護伺服器的某些資源,必須限制瀏覽器請求;要限制瀏覽器請求,必須鑑別瀏覽器請求,響應合法請求,忽略非法請求;要鑑別瀏覽器請求,必須清楚瀏覽器請求狀態。既然http協議無狀態,那就讓伺服器和瀏覽器共同維護一個狀態吧!這就是會話機制

2、會話機制

  瀏覽器第一次請求伺服器,伺服器建立一個會話,並將會話的id作為響應的一部分發送給瀏覽器,瀏覽器儲存會話id,並在後續第二次和第三次請求中帶上會話id,伺服器取得請求中的會話id就知道是不是同一個使用者了,這個過程用下圖說明,後續請求與第一次請求產生了關聯

8a9fb230-d506-4b19-b821-4001c68c4588

  伺服器在記憶體中儲存會話物件,瀏覽器怎麼儲存會話id呢?你可能會想到兩種方式

  1. 請求引數
  2. cookie

  將會話id作為每一個請求的引數,伺服器接收請求自然能解析引數獲得會話id,並藉此判斷是否來自同一會話,很明顯,這種方式不靠譜。那就瀏覽器自己來維護這個會話id吧,每次傳送http請求時瀏覽器自動傳送會話id,cookie機制正好用來做這件事。cookie是瀏覽器用來儲存少量資料的一種機制,資料以”key/value“形式儲存,瀏覽器傳送http請求時自動附帶cookie資訊

  tomcat會話機制當然也實現了cookie,訪問tomcat伺服器時,瀏覽器中可以看到一個名為“JSESSIONID”的cookie,這就是tomcat會話機制維護的會話id,使用了cookie的請求響應過程如下圖

518293d9-64b2-459c-9d45-9f353c757d1f

3、登入狀態

  有了會話機制,登入狀態就好明白了,我們假設瀏覽器第一次請求伺服器需要輸入使用者名稱與密碼驗證身份,伺服器拿到使用者名稱密碼去資料庫比對,正確的話說明當前持有這個會話的使用者是合法使用者,應該將這個會話標記為“已授權”或者“已登入”等等之類的狀態,既然是會話的狀態,自然要儲存在會話物件中,tomcat在會話物件中設定登入狀態如下

1 2 HttpSession session = request.getSession(); session.setAttribute( "isLogin" true );

  使用者再次訪問時,tomcat在會話物件中檢視登入狀態

1 2 HttpSession session = request.getSession(); session.getAttribute( "isLogin" );

  實現了登入狀態的瀏覽器請求伺服器模型如下圖描述

70e396fa-1bf2-42f8-a504-ce20306e31fa

  每次請求受保護資源時都會檢查會話物件中的登入狀態,只有 isLogin=true 的會話才能訪問,登入機制因此而實現。

二、多系統的複雜性

  web系統早已從久遠的單系統發展成為如今由多系統組成的應用群,面對如此眾多的系統,使用者難道要一個一個登入、然後一個一個登出嗎?就像下圖描述的這樣

6dfbb0b1-46c0-4945-a3bf-5f060fa80710

  web系統由單系統發展成多系統組成的應用群,複雜性應該由系統內部承擔,而不是使用者。無論web系統內部多麼複雜,對使用者而言,都是一個統一的整體,也就是說,使用者訪問web系統的整個應用群與訪問單個系統一樣,登入/登出只要一次就夠了

9fe14ab3-4254-447b-b850-0436e628c254

  雖然單系統的登入解決方案很完美,但對於多系統應用群已經不再適用了,為什麼呢?

  單系統登入解決方案的核心是cookie,cookie攜帶會話id在瀏覽器與伺服器之間維護會話狀態。但cookie是有限制的,這個限制就是cookie的域(通常對應網站的域名),瀏覽器傳送http請求時會自動攜帶與該域匹配的cookie,而不是所有cookie

4d58ccfa-0114-486d-bec2-c28f2f9eb513

  既然這樣,為什麼不將web應用群中所有子系統的域名統一在一個頂級域名下,例如“*.baidu.com”,然後將它們的cookie域設定為“baidu.com”,這種做法理論上是可以的,甚至早期很多多系統登入就採用這種同域名共享cookie的方式。

  然而,可行並不代表好,共享cookie的方式存在眾多侷限。首先,應用群域名得統一;其次,應用群各系統使用的技術(至少是web伺服器)要相同,不然cookie的key值(tomcat為JSESSIONID)不同,無法維持會話,共享cookie的方式是無法實現跨語言技術平臺登入的,比如java、php、.net系統之間;第三,cookie本身不安全。

  因此,我們需要一種全新的登入方式來實現多系統應用群的登入,這就是單點登入

三、單點登入

  什麼是單點登入?單點登入全稱Single Sign On(以下簡稱SSO),是指在多系統應用群中登入一個系統,便可在其他所有系統中得到授權而無需再次登入,包括單點登入與單點登出兩部分

1、登入

  相比於單系統登入,sso需要一個獨立的認證中心,只有認證中心能接受使用者的使用者名稱密碼等安全資訊,其他系統不提供登入入口,只接受認證中心的間接授權。間接授權通過令牌實現,sso認證中心驗證使用者的使用者名稱密碼沒問題,建立授權令牌,在接下來的跳轉過程中,授權令牌作為引數傳送給各個子系統,子系統拿到令牌,即得到了授權,可以藉此建立區域性會話,區域性會話登入方式與單系統的登入方式相同。這個過程,也就是單點登入的原理,用下圖說明

  下面對上圖簡要描述

  1. 使用者訪問系統1的受保護資源,系統1發現使用者未登入,跳轉至sso認證中心,並將自己的地址作為引數
  2. sso認證中心發現使用者未登入,將使用者引導至登入頁面
  3. 使用者輸入使用者名稱密碼提交登入申請
  4. sso認證中心校驗使用者資訊,建立使用者與sso認證中心之間的會話,稱為全域性會話,同時建立授權令牌
  5. sso認證中心帶著令牌跳轉會最初的請求地址(系統1)
  6. 系統1拿到令牌,去sso認證中心校驗令牌是否有效
  7. sso認證中心校驗令牌,返回有效,註冊系統1
  8. 系統1使用該令牌建立與使用者的會話,稱為區域性會話,返回受保護資源
  9. 使用者訪問系統2的受保護資源
  10. 系統2發現使用者未登入,跳轉至sso認證中心,並將自己的地址作為引數
  11. sso認證中心發現使用者已登入,跳轉回系統2的地址,並附上令牌
  12. 系統2拿到令牌,去sso認證中心校驗令牌是否有效
  13. sso認證中心校驗令牌,返回有效,註冊系統2
  14. 系統2使用該令牌建立與使用者的區域性會話,返回受保護資源

  使用者登入成功之後,會與sso認證中心及各個子系統建立會話,使用者與sso認證中心建立的會話稱為全域性會話,使用者與各個子系統建立的會話稱為區域性會話,區域性會話建立之後,使用者訪問子系統受保護資源將不再通過sso認證中心,全域性會話與區域性會話有如下約束關係

  1. 區域性會話存在,全域性會話一定存在
  2. 全域性會話存在,區域性會話不一定存在
  3. 全域性會話銷燬,區域性會話必須銷燬

  你可以通過部落格園、百度、csdn、淘寶等網站的登入過程加深對單點登入的理解,注意觀察登入過程中的跳轉url與引數

2、登出

  單點登入自然也要單點登出,在一個子系統中登出,所有子系統的會話都將被銷燬,用下面的圖來說明

3b139d2e-0b83-4a69-b4f2-316adb8997ce

  sso認證中心一直監聽全域性會話的狀態,一旦全域性會話銷燬,監聽器將通知所有註冊系統執行登出操作

  下面對上圖簡要說明

  1. 使用者向系統1發起登出請求
  2. 系統1根據使用者與系統1建立的會話id拿到令牌,向sso認證中心發起登出請求
  3. sso認證中心校驗令牌有效,銷燬全域性會話,同時取出所有用此令牌註冊的系統地址
  4. sso認證中心向所有註冊系統發起登出請求
  5. 各註冊系統接收sso認證中心的登出請求,銷燬區域性會話
  6. sso認證中心引導使用者至登入頁面

四、部署圖

  單點登入涉及sso認證中心與眾子系統,子系統與sso認證中心需要通訊以交換令牌、校驗令牌及發起登出請求,因而子系統必須整合sso的客戶端,sso認證中心則是sso服務端,整個單點登入過程實質是sso客戶端與服務端通訊的過程,用下圖描述

fb29685c-487c-42b9-9ceb-6c7ee29e98c9

  sso認證中心與sso客戶端通訊方式有多種,這裡以簡單好用的httpClient為例,web service、rpc、restful api都可以

五、實現

  只是簡要介紹下基於java的實現過程,不提供完整原始碼,明白了原理,我相信你們可以自己實現。sso採用客戶端/服務端架構,我們先看sso-client與sso-server要實現的功能(下面:sso認證中心=sso-server)

  sso-client

  1. 攔截子系統未登入使用者請求,跳轉至sso認證中心
  2. 接收並存儲sso認證中心傳送的令牌
  3. 與sso-server通訊,校驗令牌的有效性
  4. 建立區域性會話
  5. 攔截使用者登出請求,向sso認證中心傳送登出請求
  6. 接收sso認證中心發出的登出請求,銷燬區域性會話

  sso-server

  1. 驗證使用者的登入資訊
  2. 建立全域性會話
  3. 建立授權令牌
  4. 與sso-client通訊傳送令牌
  5. 校驗sso-client令牌有效性
  6. 系統註冊
  7. 接收sso-client登出請求,登出所有會話

  接下來,我們按照原理來一步步實現sso吧!

1、sso-client攔截未登入請求

  java攔截請求的方式有servlet、filter、listener三種方式,我們採用filter。在sso-client中新建LoginFilter.java類並實現Filter介面,在doFilter()方法中加入對未登入使用者的攔截

1 2 3 4 5 6 7 8 9 10 11 12 public  void  doFilter(ServletRequest request, ServletResponse response, FilterChain chain)  throws  IOException, ServletException {      HttpServletRequest req = (HttpServletRequest) request;      HttpServletResponse res = (HttpServletResponse) response;      HttpSession session = req.getSession();            if  (session.getAttribute( "isLogin" )) {          chain.doFilter(request, response);          return ;      }      //跳轉至sso認證中心      res.sendRedirect( "sso-server-url-with-system-url" ); }

2、sso-server攔截未登入請求

  攔截從sso-client跳轉至sso認證中心的未登入請求,跳轉至登入頁面,這個過程與sso-client完全一樣

3、sso-server驗證使用者登入資訊

  使用者在登入頁面輸入使用者名稱密碼,請求登入,sso認證中心校驗使用者資訊,校驗成功,將會話狀態標記為“已登入”

相關推薦

登入原理簡單實現 登入原理簡單實現

單點登入原理與簡單實現   (2017-09-22更新)GitHub:https://github.com/sheefee/simple-sso 一、單系統登入機制 1、http無狀態協議   web應用採用browser/server架構,http作為通訊

無限極分類原理實現

轉換 完成 外灘 獲得 意思 容易 set 導航 另一個   前言   無限極分類是我很久前學到知識,今天在做一個項目時,發現對其概念有點模糊,所以今天就來說說無限極分類。   首先來說說什麽是無限極分類。按照我的理解,就是對數據完成多次分類,如同一棵樹一樣,從根開始,

網口掃盲二:MacPhy組成原理簡單分析

  1. general 下圖是網口結構簡圖.網口由CPU、MAC和PHY三部分組成.DMA控制器通常屬於CPU的一部分,用虛線放在這裡是為了表示DMA控制器可能會參與到網口資料傳輸中.             &

Redis 設計實現 --多機數據庫的實現

緩沖 所有 moved 啟動 tin 當前 body ica red 多機數據庫的實現 一、復制   slaveof 主服務器ip地址。形成主從關系。   1、同步       從向主服務器發送sync命令。     主服務器收到sync命令執行bgsav

程序執行緒——執行緒的概念實現

一 什麼是執行緒? 程序中的一條執行流程。 有了執行緒,程序發生了一系列的變化。首先是(1)資源管理,包括地址空間(程式碼段,資料段):程序就是由來管理資源的:地址空間,開啟的檔案,訪問的網路。(2)執行緒把程序的另一部分功能給拆出來了。 程序的執行功能,程序的

Dubbo原理解析-Dubbo核心實現之基於SPI思想Dubbo核心實現

SPI介面定義 定義了@SPI註解 public @interface SPI {   String value() default ""; //指定預設的擴充套件點 } 只有在介面打了@SPI註解的介面類才會去查詢擴充套件點實現 會依次從這幾個檔案中讀取擴

【進階3-4期】深度解析bind原理、使用場景及模擬實現

這是我在公眾號(高階前端進階)看到的文章,現在做筆記  https://github.com/yygmind/blog/issues/23 bind() bind() 方法會建立一個新函式,當這個新函式被呼叫時,它的 this 值是傳遞給 bind(

【進階3-5期】深度解析 new 原理及模擬實現

這是我在公眾號(高階前端進階)看到的文章,現在做筆記 https://github.com/yygmind/blog/issues/24 new 運算子建立一個使用者定義的物件型別的例項或具有建構函式的內建物件的例項。 ——(來自於MDN) 舉個例子: function Car(color) {

答題微信小程式實現2選計數

不太習慣用新版寫東西,還是markdown寫著習慣。 我也是一個初學者,所以把目的拆分成一個個小模組,分別實現吧。 答題和隨機的原始框架在(1)中已經實現了。 那麼這篇就寫積分。也就是答對一題,加1分。這裡簡化成點選一次加1分。 好開森,點選計數的功能終

動態載入外掛系統的初步實現:AppDomain解除安裝代理

前一篇文章簡單展示了型別發現和MEF使用,本文初步進入AppDomain相關內容。 CLR程式執行時會建立預設程式集容器即AppDomain,預設AppDomain不支援解除安裝其程式集,但CLR支援建立和解除安裝AppDomain,這意味著我們可以間接地通過額外的AppDomain實現外掛的熱插拔。

Unity3d設計模式例模式

為什麼要使用單例模式 在我們的整個遊戲生命週期當中,有很多物件從始至終有且只有一個。這個唯一的例項只需要生成一次,並且直到遊戲結束才需要銷燬。 單例模式一般應用於管理器類,或者是一些需要持久化存在的物件。 Unity3d中單例模式的實現方式 (一

截圖功能實現自動框選原理

        觀察其他截圖工具比如QQ 當滑鼠在某個視窗是會自動把某個視窗高亮顯示,這個功能其實還是很有用的它可以加快截圖時間,可以更快的完成截圖,於是乎我也尋思著如何去實現這個功能,網上翻來翻去好幾天都沒什麼進展,有一天無意間發現一個截圖的Demo有這個功能,因此研究了

ProtoBuf.js – Protocol Buffers的Javascript實現

line 解決 進行 序列 blank read tar com json 原文鏈接:ProtoBuf.js – Protocol Buffers的Javascript實現 推薦前端網址:http://keenwon.com/ 在Javascript裏比較常見的數據格式就是

關於長鏈接,短鏈接,異步,同步,工,雙工的定義

ref duplex link targe href 超時 spa 數據包 影響 長連接:指在一個TCP連接上可以連續發送多個數據包,在TCP連接保持期間,如果沒有數據包發送,需要雙方發檢測包以維持此連接,一般需要自己做在線維持。 短連接:是指通信雙方有數

【經典數據結構】B樹B+樹

linux 每分鐘 www 數據 csapp png 感知 轉動 繼續 本文轉載自:http://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.html 維基百科對B樹的定義為“在計算機科學中,B

八大排序算法python實現

n) 順序 tails detail 時間 tail 哨兵 插入元素 lang 一、概述 排序有內部排序和外部排序,內部排序是數據記錄在內存中進行排序,而外部排序是因排序的數據很大,一次不能容納全部的排序記錄,在排序過程中需要訪問外存。

JVM基礎:深入學習JVM堆JVM棧

面向 對象的引用 進入 信息 分離 字節 address 出現 運行 JVM棧解決程序的運行問題,即程序如何執行,或者說如何處理數據;JVM堆解決的是數據存儲的問題,即數據怎麽放、放在哪兒,另外JVM堆中存的是對象。JVM棧中存的是基本數據類型和JVM堆中對象的引用。 JV

Yii 2.0 數據庫簡單操作

conf enables sel base attr brush 個數 對象 創建數據庫   開始使用數據庫首先需要配置數據庫連接組件,通過添加 db 組件到應用配置實現("基礎的" Web 應用是 config/web.php),DSN( Data Source Name

CST,CET,UTC,GMT,DST,Unix時間戳幾種常見時間概述關系

使用 ndb 過程 發布 英國倫敦 國家 包括 世界時間 com 轉自:http://www.cnblogs.com/frontendBY/p/5215785.html 1、UTC: Universal Time Coordinated 協調世界時,又稱世界標準時間

Java靜態檢測工具/Java代碼規範和質量檢查簡單介紹

pub 詳細 職責 web 循環 問題: 集成 死鎖 參考 靜態檢查: 靜態測試包括代碼檢查、靜態結構分析、代碼質量度量等。它可以由人工進行,充分發揮人的邏輯思維優勢,也可以借助軟件工具自動進行。代碼檢查代碼檢查包括代碼走查、桌面檢查、代碼審查等,主要檢查代碼和設計的一致