單點登入系統原理與實現,圖文並茂,附原始碼
本原文:整理自網際網路
一、單系統登入機制
1、http無狀態協議
web應用採用browser/server架構,http作為通訊協議。http是無狀態協議,瀏覽器的每一次請求,伺服器會獨立處理,不與之前或之後的請求產生關聯,這個過程用下圖說明,三次請求/響應對之間沒有任何聯絡。
2、會話機制
瀏覽器第一次請求伺服器,伺服器建立一個會話,並將會話的id作為響應的一部分傳送給瀏覽器,瀏覽器儲存會話id,並在後續第二次和第三次請求中帶上會話id,伺服器取得請求中的會話id就知道是不是同一個使用者了,這個過程用下圖說明,後續請求與第一次請求產生了關聯。
3、登入狀態
有了會話機制,登入狀態就好明白了,我們假設瀏覽器第一次請求伺服器需要輸入使用者名稱與密碼驗證身份,伺服器拿到使用者名稱密碼去資料庫比對,正確的話說明當前持有這個會話的使用者是合法使用者,應該將這個會話標記為“已授權”或者“已登入”等等之類的狀態,既然是會話的狀態,自然要儲存在會話物件中,tomcat在會話物件中設定登入狀態如下。
HttpSession session = request.getSession();session.setAttribute("isLogin", true);
使用者再次訪問時,tomcat在會話物件中檢視登入狀態
HttpSession session = request.getSession();session.getAttribute("isLogin");
實現了登入狀態的瀏覽器請求伺服器模型如下圖描述
每次請求受保護資源時都會檢查會話物件中的登入狀態,只有 isLogin=true 的會話才能訪問,登入機制因此而實現。
二、多系統的複雜性
單系統登入解決方案的核心是cookie,cookie攜帶會話id在瀏覽器與伺服器之間維護會話狀態。但cookie是有限制的,這個限制就是cookie的域(通常對應網站的域名),瀏覽器傳送http請求時會自動攜帶與該域匹配的cookie,而不是所有cookie。
因此,我們需要一種全新的登入方式來實現多系統應用群的登入,這就是單點登入。
三、單點登入
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使用該令牌建立與使用者的區域性會話,返回受保護資源
你可以透過部落格園、百度、csdn、淘寶等網站的登入過程加深對單點登入的理解,注意觀察登入過程中的跳轉url與引數。
2、登出
單點登入自然也要單點登出,在一個子系統中登出,所有子系統的會話都將被銷燬,用下面的圖來說明。
1、使用者向系統1發起登出請求 2、系統1根據使用者與系統1建立的會話id拿到令牌,向sso認證中心發起登出請求 3、sso認證中心校驗令牌有效,銷燬全域性會話,同時取出所有用此令牌註冊的系統地址 4、sso認證中心向所有註冊系統發起登出請求 5、各註冊系統接收sso認證中心的登出請求,銷燬區域性會話 6、sso認證中心引導使用者至登入頁面
四、部署圖
sso認證中心與sso客戶端通訊方式有多種,這裡以簡單好用的httpClient為例,web service、rpc、restful api都可以。
五、實現
只是簡要介紹下基於java的實現過程,不提供完整原始碼,明白了原理,我相信你們可以自己實現。sso採用客戶端/服務端架構,我們先看sso-client與sso-server要實現的功能(下面:sso認證中心=sso-server)
sso-client
sso-server
接下來,我們按照原理來一步步實現sso吧!
1、sso-client攔截未登入請求
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攔截未登入請求
3、sso-server驗證使用者登入資訊
使用者在登入頁面輸入使用者名稱密碼,請求登入,sso認證中心校驗使用者資訊,校驗成功,將會話狀態標記為“已登入”
@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建立授權令牌
授權令牌是一串隨機字元,以什麼樣的方式生成都沒有關係,只要不重複、不易偽造即可,下面是一個例子
String token = UUID.randomUUID().toString();
5、sso-client取得令牌並校驗
sso認證中心登入後,跳轉回子系統並附上令牌,子系統(sso-client)取得令牌,然後去sso認證中心校驗,在LoginFilter.java的doFilter()中新增幾行
// 請求附帶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詳細使用方法請參考官方文件
HttpPost httpPost = new HttpPost("sso-server-verify-url-with-token");HttpResponse httpResponse = httpClient.execute(httpPost);
6、sso-server接收並處理校驗令牌請求
7、sso-client校驗令牌成功建立區域性會話
if (verifyResult) { session.setAttribute("isLogin", true);}
sso-client還需將當前會話id與令牌繫結,表示這個會話的登入狀態與令牌相關,此關係可以用java的hashmap儲存,儲存的資料用來處理sso認證中心發來的登出請求
8、登出過程
String logout = req.getParameter("logout");if (logout != null) { this.ssoServer.logout(token);}
sso認證中心也用同樣的方式識別出sso-client的請求是登出請求(帶有“logout”引數),sso認證中心登出全域性會話
@RequestMapping("/logout")public String logout(HttpServletRequest req) { HttpSession session = req.getSession(); if (session != null) { session.invalidate();//觸發LogoutListener } return "redirect:/";}
sso認證中心有一個全域性會話的監聽器,一旦全域性會話登出,將通知所有註冊系統登出
public class LogoutListener implements HttpSessionListener { @Override public void sessionCreated(HttpSessionEvent event) {} @Override public void sessionDestroyed(HttpSessionEvent event) { //透過httpClient向所有註冊系統傳送登出請求 }}
GitHub:點個再看唄,鳥哥有肉吃
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31557372/viewspace-2658852/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 單點登入原理與簡單實現
- 從JMM透析volatile與synchronized原理,圖文並茂synchronized
- 單點登入原理與技術實現比較
- 單點登入 SSO 的實現原理
- 跨域分散式系統單點登入的實現(CAS單點登入)跨域分散式
- 實現TouchID指紋解鎖(圖文並茂)
- Flutter 入門與實戰(五):來一個圖文並茂的列表Flutter
- Springboot快速入門篇,圖文並茂Spring Boot
- 單點登入原理
- 菜鳥學SSH(一)——Struts實現簡單登入(附原始碼)原始碼
- CAS實現單點登入SSO執行原理探究
- 圖文並茂排序與演算法總結排序演算法
- Promise實現原理(附原始碼)Promise原始碼
- 直播系統原始碼,自動登入及記住密碼實現原始碼密碼
- 一文弄懂宇宙的歷史與結構(圖文並茂)!
- 使用CAS實現單點登入
- 圖文並茂詳解 NAT 協議!協議
- 字首和與差分 圖文並茂 超詳細整理
- 如何自己實現一個健壯的 SSO 單點登入系統
- java實現簡單的單點登入Java
- Casdoor + OAuth 實現單點登入 SSOOAuth
- 萬字長文+圖文並茂+全面解析微前端框架 qiankun 原始碼 - qiankun 篇前端框架原始碼
- 原始碼分析 Alibaba sentinel 滑動視窗實現原理(文末附原理圖)原始碼
- 水星路由器設定圖文並茂路由器
- IM的掃碼登入功能如何實現?一文搞懂主流的掃碼登入技術原理
- SSO單點登入最全詳解(圖文全面總結)
- CAS實現單點登入SSO執行原理探究(終於明白了)
- 單點登入的原理、實現、及技術方案比較詳解
- HashMap 實現原理與原始碼分析HashMap原始碼
- 圖文並茂的神經網路架構大盤點:從基本原理到衍生關係神經網路架構
- 訊息中介軟體-RabbitMq相關概念及原理介紹【圖文並茂】MQ
- OAuth2實現單點登入SSOOAuth
- 單點登入的三種實現方式
- 22 CAS實現單點登入體驗
- 什麼是單點登入?如何實現?
- 用j2ee如何實現applet系統的單點登入APP
- Git入門圖文教程(1.5W字40圖)??--深入淺出、圖文並茂Git
- Git學習-圖文並茂還有遊戲玩!Git遊戲