前言: 單點登錄其實是一個概念,主要是為了解決一次登錄,多系統(本系統或外部系統)之間不需要重復登錄的問題,就目前來說,主流的解決方案針對業務場景分為3個方向:
1: 同一公司,同父域下的單點登錄解決方案.
如[http://map.baidu.com] [http://www.baidu.com] [http://image.baidu.com]
基於cookie開源項目代表: JWT(https://jwt.io/);
需要注意jwt token存儲在哪里的問題:
首先我們要明確csrf和xss兩種漏洞的不同之處:
2: 同一公司,不同域下的單點登錄解決方案.
如[http://www.taobao.com] [http://www.tmall.com]
基於中央認證服務器開源項目代表:CAS(https://github.com/apereo/cas); https://www.apereo.org/projects/cas
Request1
【第一步】終端第一次訪問CAS—Client1,AuthenticationFilter會截獲此請求:
1、首先,檢測本地Session沒有緩存有用戶信息;
2、然后,檢測到請求信息中沒有ST;
3、所以,CAS—Client1將請求重定向到CAS—Server,並傳遞 Service (也就是要訪問的目的資源地址,以便登錄成功過后轉回該地址),例:【https://cas:8443/cas/login?service=http0%3A8081%2F】
【第二步】終端第一次訪問CAS—Server:
1、CAS—Server檢測到請求信息中沒有TGC,所以跳轉到自己的登錄頁;
2、終端輸入用戶名、密碼登錄CAS—Server,認證成功后,CAS—Server會生成登錄票據—TGT(集成了用戶信息與ST),並隨機生成一個服務票據—ST 與 CAS會話標識—TGC。
TGT實際上就是Session,而TGC就是這標識這個Session存到Cookie中的SessionID;ST即,根據Service生成Ticket。
3、然后,CAS—Server會將Ticket加在url 后面,然后將請求redirect 回客戶web 應用,例如URL為【http://192.168.1.1:8081/web1/?ticket=ST-5-Sx6eyvj7cPPCfn0pMZ】
【第三步】這時,終端攜帶ticket再次請求CAS—Client1:
1、這時客戶端的AuthenticationFilter看到ticket 參數后,會跳過,由其后面的TicketValidationFilter 處理;
2、TicketValidationFilter 會利用httpclient工具訪問cas 服務的/serviceValidate 接口, 將ticket 、service 都傳到此接口,由此接口驗證ticket 的有效性,即向CAS—Server驗證ST的有效性。
3、TicketValidationFilter如果得到驗證成功的消息,就會把用戶信息寫入web 應用的session里。至此為止,SSO 會話就建立起來了
Request2
上面說SSO 會話已經建立起來了,用戶在同一瀏覽器里第二次訪問此web 應用(CAS—Client1)時,AuthenticationFilter會在session 里讀取到用戶信息,這就代表用戶已成功登錄,就不會CAS 認證了。
Request3
【第一步】與Request1是完全一樣的,如下:終端第一次訪問CAS—Client2,AuthenticationFilter會截獲此請求:
1、首先,檢測本地Session沒有緩存有用戶信息;
2、然后,檢測到請求信息中沒有ST;
3、所以,CAS—Client1將請求重定向到CAS—Server,並傳遞 Service (也就是要訪問的目的資源地址,以便登錄成功過后轉回該地址),例:【https://cas:8443/cas/login?service=http0%3A8081%2F】
【第二步】然后,終端第二次訪問CAS—Server:此時,Request中會帶有上次生成的TGC,然后根據TGC(SessionID)去查找是否有對應的TGT(Session),如果有,代表此用戶已成功登錄過,所以此時用戶不必再去登錄頁登錄(SSO的體現),而CAS—Server會直接用找到的TGT簽發一個ST,然后重定向到CAS—Client2,剩下的如Request1中的【第三步】就完全一樣了。
3: 不同公司之間,不同域下的 第三方登錄功能實現.
如第三方網站支持qq登錄,微信登錄,微博登錄等;
基於OAuth2.0協議各大公司自己的支持;
沒有用過,不太了解,不過微信公眾號開發獲取用戶授權好像就是oauth2.0,那首先用戶授權登錄獲取一個到code,拿到code換取access_token,然后就能使用access_token來獲取用戶信息了