單點登錄三個方法及原理:
- 共享Session
- 基于OpenId的單點登錄
- 基于Cookie的OpenId存儲方案
共享Session
共享Session可謂是實現單點登錄最直接、最簡單的方式鼻疮。將用戶認證信息保存于Session中比规,即以Session內存儲的值為用戶憑證兴枯,這在單個站點內使用是很正常也很容易實現的,而在用戶驗證摆舟、用戶信息管理與業(yè)務應用分離的場景下即會遇到單點登錄的問題丰泊,在應用體系簡單汇恤,子系統(tǒng)很少的情況下,可以考慮采用Session共享的方法來處理這個問題访锻。
基于Redis的Session共享方案褪尝。將Session存儲于Redis上,然后將整個系統(tǒng)的全局Cookie Domain設置于頂級域名上期犬,這樣SessionID就能在各個子系統(tǒng)間共享河哑。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
String JSESSIONID = request.getSession().getId();//獲取當前JSESSIONID (不管是從主域還是二級域訪問產生)
Cookie cookie = new Cookie("JSESSIONID", JSESSIONID);
cookie.setDomain(".test.com"); //關鍵在這里,將cookie設成主域名訪問龟虎,確保不同域之間都能獲取到該cookie的值璃谨,從而確保session統(tǒng)一
response.addCookie(cookie); //將cookie返回到客戶端
request.getRequestDispatcher("indes.jsp").forward(request, response);
%>
基于OpenId的單點登錄
- 當用戶第一次登錄時,將用戶名密碼發(fā)送給驗證服務鲤妥;
- 驗證服務將用戶標識OpenId返回到客戶端佳吞;
- 客戶端進行存儲;
- 訪問子系統(tǒng)時旭斥,將OpenId發(fā)送到子系統(tǒng)容达;
- 子系統(tǒng)將OpenId轉發(fā)到驗證服務;
- 驗證服務將用戶認證信息返回給子系統(tǒng)垂券;
- 子系統(tǒng)構建用戶驗證信息后將授權后的內容返回給客戶端花盐。
基于Cookie的OpenId存儲方案
- 在提供驗證服務的站點里登錄;
- 將OpenId寫入頂級域名Cookie里菇爪;
- 訪問子系統(tǒng)(Cookie里帶有OpenId)
- 子系統(tǒng)取出OpenId通過并向驗證服務發(fā)送OpenId
- 返回用戶認證信息
- 返回授權后的內容
B/S多域名環(huán)境下的單點登錄處理
在多個頂級域名的情況下算芯,我們將無法讓各個子系統(tǒng)的OpenId共享。處理B/S環(huán)境下的跨域問題凳宙,我們首先就應該想到JSONP的方案熙揍。
驗證步驟如下:
- 用戶通過登錄子系統(tǒng)進行用戶登錄;
- 用戶登錄子系統(tǒng)記錄了用戶的登錄狀態(tài)氏涩、OpenId等信息届囚;
- 用戶使用業(yè)務子系統(tǒng)有梆;
- 若用戶未登錄業(yè)務子系統(tǒng)則將用戶跳轉至用戶登錄子系統(tǒng);
- 用戶子系統(tǒng)通過JSONP接口將用戶OpenId傳給業(yè)務子系統(tǒng)意系;
- 業(yè)務子系統(tǒng)通過OpenId調用驗證服務泥耀;
- 驗證服務返回認證信息、業(yè)務子系統(tǒng)構造用戶登錄憑證蛔添;(此時用戶客戶端已經與子業(yè)務系統(tǒng)的驗證信息已經一一對應)
- 將用戶登錄結果返回用戶登錄子系統(tǒng)痰催,若成功登錄則將用戶跳轉回業(yè)務子系統(tǒng);
- 將授權后的內容返回客戶端迎瞧;
安全問題
在整個開發(fā)過程初期夸溶,我們采用用戶表中紀錄一個OpenId字段來保存用戶OpenId,而這個機制下很明顯存在一些安全性凶硅、擴展性問題缝裁。這個擴展性問題主要體現在一個方面:OpenId的安全性和用戶體驗的矛盾。
整個單點登錄的機制決定了OpenId是會出現在客戶端的咏尝,所以OpenId需要有過期機制压语,假如用戶在一個終端登錄的話可以選擇在用戶每次登錄或者每次退出時刷新OpenId,而在多終端登錄的情況下就會出現矛盾:當一個終端刷新了OpenId之后其他終端將無法正常授權编检。而最終胎食,我采用了單用戶多OpenId的解決方案。每次用戶通過用戶名/密碼登錄時允懂,產生一個OpenId保存在Redis里厕怜,并且設定過期時間,這樣多個終端登錄就會有多個OpenId與之對應蕾总,不再會存在一個OpenId失效所有終端驗證都失效的情況粥航。