web登陸分析(簡單登陸與單點登陸)

簡單登陸

登陸流程

首先讓咱們分析一下一個簡單的登陸是怎麼實現的。php

  1. 一個簡單的登陸流程java

    • 用戶輸入url訪問站點,接受用戶請求後判斷用戶是否已經登陸,若未登陸則跳轉到登陸頁面
    • 用戶訪問登陸頁面,填寫並提交登陸表單
    • web應用對登陸表單進行驗證,若驗證失敗,則返回錯誤信息給用戶;若驗證成功,則將用戶相關的信息(一般爲用戶id等信息)寫入到當前的session中,將session id以cookie的形式發送給用戶(同時能夠將session中的身份信息以cookie的形式發送給用戶,這個是可選的,使用該cookie能夠實現自動登陸,以下面的「登陸分析圖」中所示)。
    • 用戶登陸後,後續的訪問中會將其得到的包含session id的cookie傳遞給web應用,若web應用能根據session id從session中獲取到相應的身份信息(甚至進一步從數據庫查找到相關的用戶數據),則表明用戶成功登陸。
  2. 退出登陸
    退出登陸主要包括如下兩個流程web

    • 銷燬session信息 (在服務端銷燬)
    • 銷燬客戶端的相關cookie(包含session id的cookie)

自動登陸

一般來講,服務器端的session會有必定的過時時間,一樣的,客戶端中包含session id的cookie也有過時時間。若用戶登陸後,長時間沒有發出訪問請求,則等到用戶再次訪問時,可能服務端的session或客戶端的cookie已經失效,致使服務器判斷用戶爲「未登陸」,而實際上用戶並無退出登陸過。能夠經過實現「自動登陸」來解決這個問題,即在session失效的時候,能夠從新自動登陸。數據庫

自動登陸的基本思路:跨域

  1. 在用戶登陸後,除了生成session id對應的cookie,還會生成一個包含用戶身份信息的cookie(假設這個cookie的key爲identity)。identity cookie包含的信息能夠有:用戶id,用戶authKey(這個比較重要,authKey的功能有點相似於password),cookie持續時間等。爲了達到自動登陸的目的,一般會將該cookie的過時時間設置的特別長(能夠是一個星期甚至一個月)。
  2. 在用戶session失效後,用戶再次訪問web應用,會帶上identity cookie(由於該cookie的有效期較長)。web應用首先判斷用戶爲「未登陸」狀態(由於session失效了)。
  3. web應用嘗試經過identity cookie爲用戶自動登陸。應用從identity cookie中獲取「用戶id」和「用戶authKey」,經過與數據庫中的數據進行對比,校驗「用戶authKey」的有效性。
  4. 用戶authKey認證有效後,web應用爲用戶生成新的session,並將新的session id放入cookie發送給用戶。(即用戶登陸成功的標誌爲獲取到包含session id的cookie)

例子分析(yii1.1與yii2)

  1. yii1.1原生登陸分析
    yii1.1原生登陸分析

    原文件和圖片下載百度雲盤連接tomcat

  2. yii2原生登陸分析
    圖片描述

    原文件和圖片下載百度雲盤連接安全

小結

  1. cookie,session是實現登陸的核心
  2. 對應關係鏈: 客戶端的cookie(包含了session id) ---> session id對應服務器端的session(包含了用戶的身份信息,如id) ---> 根據session中的信息,能夠進一步從數據庫中獲取用戶的詳細信息(甚至是其相應的權限)

單點登陸介紹

什麼是單點登陸?

單點登陸(Single sign-on,縮寫爲 SSO),又譯爲單一簽入,一種對於許多相互關連,可是又是各自獨立的軟件系統,提供訪問控制的屬性。在擁有這項屬性的環境中,當用戶在某個系統登陸時,就能夠獲取全部系統的訪問權限,不用對每一個單一系統都逐一登陸。這項功能一般是以輕型目錄訪問協議(LDAP)來實現,在服務器上會將用戶信息存儲到LDAP數據庫中。相同的,單一註銷(single sign-off)就是指,只須要單一的註銷動做,就能夠結束對於多個系統的訪問權限。(即,在多個應用系統中,用戶只須要登陸一次就能夠訪問全部相互信任的應用系統;用戶只須要退出登陸一次就能夠退出全部的應用系統服務器

單點登陸的優勢

  • 下降訪問第三方網站風險(用戶密碼不存儲或外部管理)。
  • 用戶不須要在不一樣的站點使用不一樣的用戶名和密碼,減小「密碼疲勞」(password fatigue )。
  • 減小在使用不一樣站點時花費時間來從新輸入密碼進行身份驗證。
  • 下降IT成本。

web單點登陸的基本思路

  1. 當用戶第一次訪問應用系統1的時候,由於尚未登陸,會被引導到認證系統中進行登陸(1)
  2. 根據用戶提供的登陸信息, 認證系統進行身份校驗,若是經過效校驗,返回給用戶一個認證的憑據ticket(2)
  3. 用戶從新訪問應用系統1,此時會帶上ticket。應用系統1接受到請求後會把ticket發送到認證系統進行校驗,檢查ticket的合法性;若ticket合法性驗證經過(表明用戶已經登陸),則用戶能夠訪問應用系統1
  4. 用戶再訪問別的應用的時候(3,5)也會將這個ticket 帶上,做爲本身認證的憑據,應用系統接受到請求以後會把ticket送到認證系統進行效驗,檢查ticket的合法性(4,6)。若是經過效驗,用戶就能夠在不用再次登陸的狀況下訪問應用系統2和應用系統3了。
  • 單點登陸機制

總結:ticket是整個系統的核心,ticket會在用戶,應用系統,認證系統的交互中傳輸,最終達到實現單點登陸的目的。ticket是全部系統對用戶的統一的認證標誌。yii2

單點登陸會遇到的問題

Q1:ticket是什麼?由什麼組成?
正如前面所說,ticket是全部系統對用戶的統一的認證標誌。在具體的實現中,咱們能夠用cookie來實現ticket的功能。最簡單的,一個包含session id的cookie就能夠當作是一個ticket。在後續對具體實現的分析中,咱們會更深刻地理解ticket。出於安全須要,一般咱們會對ticket進行加密。要實現SSO的功能,讓用戶只登陸一次,就必須讓應用系統可以識別已經登陸過的用戶。應用系統應該能對ticket進行識別和提取,經過與認證系統的通信,能自動判斷當前用戶是否登陸過,從而完成單點登陸的功能。 cookie

Q2:單點登陸在技術實現上有哪些分類?
在技術實現上,單點登陸能夠分爲跨子域單點登陸徹底跨域單點登陸

Q3:什麼是跨子域單點登陸?其實現的具體思路是什麼?
跨子域單點登陸即在具備相同根域名的站點之間實現單點登陸。例如,有如下站點a.example.com, b.example.com, p.example.com(認證中心),它們都有一個共同的根域名「example.com」。在單點登陸寫cookie時,把cookie的域設爲它們共同的父域(即「example.com」),這樣在不一樣的子域名下均可以使用同一個cookie(即ticket);與此同時,可讓多個系統共享session信息。

Q4:什麼是徹底跨域單點登陸?其實現的具體思路是什麼?
徹底跨域單點登陸即具備不一樣根域名的站點之間實現單點登陸。實現思路:每一個站點須要有本身的ticket(A-tikcet,B-ticket,P-ticket);當訪問應用系統(A,B)時,若沒有相應的ticket,則自動重定向到認證系統(P),在認證系統認證得到P-ticket後重定向到應用系統(A或B),用P-tikcet換取相應的A-ticket或B-ticket;註銷的時候要註銷全部的ticket(P-ticket,A-ticket,B-ticket)

Q5:Q3中共享cookie的方式存在什麼侷限?
首先,應用羣域名得統一;其次,應用羣各系統使用的技術(至少是web服務器)要相同,否則cookie的key值(tomcat爲JSESSIONID,php爲PHPSESSID)不一樣,沒法維持會話,共享cookie的方式是沒法實現跨語言技術平臺登陸的,好比java、php、.net系統之間;第三,cookie自己不安全。


單點登陸實現

跨子域單點登陸

跨子域單點登陸的實現相對比較簡單,能夠基於cookie來實現,基本思想以下:

  1. 前提: 應用羣中各個站點的域名須要統一,即具備相同的根域名;應用羣使用的技術要相同,這樣纔可以維持回話(例如tomcat下cookie的key值爲JSESSIONID,而PHP技術棧下則爲PHPSESSID)
  2. 在前面所述的「web單點登陸的基本思路」的基礎上,將ticket具體實現爲cookie中的session id,而且能夠省略應用到認證中心對ticket進行校驗的步驟。

具體圖示以下:
單點登陸時序圖(跨子域單點登陸)

1.當用戶訪問系統1(域名爲a.example.com)時,系統檢測到用戶的請求中沒有ticket(即沒有相應的cookie),則判斷用戶未登陸,將用戶重定向到認證中心(帶上系統1的url,則認證完後認證中心可將用戶重定向會系統1)

2.用戶提交登陸表單到認證中心,驗證經過後建立相應的session。將session id做爲ticket,以cookie的方式發送給用戶,並將用戶重定向到系統1。(注意,cookie的域爲根域「example.com」

3.用戶重定向到系統1(此時會帶上相應的cookie做爲ticket)。系統1檢測到有ticket,則向認證中心發起請求,驗證ticket的有效性。

4.認證中心驗證ticket的有效性(即確實有對應的session),將校驗結果返回給系統1

5.系統1從認證中心獲得校驗成功的結果後,則能夠認爲用戶「已登陸」。

6.用戶繼續訪問系統2(由於系統2的域名爲「b.example.com」,其根域名也爲「example.com」,故此時會帶上相應的cookie做爲ticket)。系統2檢測到有ticket,則向認證中心發起請求,驗證ticket的有效性。

7.認證中心驗證ticket的有效性(即確實有對應的session),將校驗結果返回給系統2。

8.系統2從認證中心獲得校驗成功的結果後,則能夠認爲用戶「已登陸」。

徹底跨域單點登陸

徹底跨域單點登陸的實現思路正如前面所述,這裏複述一下:
1.每一個站點須要有本身的ticket(假設:系統1爲A-tikcet,系統2爲B-ticket,認證中心爲P-ticket)
2.當訪問應用系統(系統1,系統2)時,若沒有相應的ticket,則自動重定向到認證系統(P),在認證系統認證得到P-ticket後重定向到應用系統(系統1或系統2),用P-tikcet換取相應的A-ticket或B-ticket;註銷的時候要註銷全部的ticket(P-ticket,A-ticket,B-ticket)

具體圖示以下:
注意: 在具體的實現中,能夠用cookie來實現tikcet。ticket能夠是包含session id的cookie。
單點登陸時序圖(徹底跨域單點登陸)

1.用戶訪問系統1,系統1發現用戶未登陸(沒有A-ticket),跳轉至認證中心,並帶上系統的url做爲參數(即回調url,這樣認證後就能夠跳轉回來了)。

2.認證中心發現用戶未登陸(沒有P-ticket),將用戶引導至登陸界面。

3.用戶提交登陸信息到認證中心。

4.認證中心校驗用戶的登陸信息,經過驗證後,建立一個全局session,生成一個綁定當前session的P-ticket。而後將P-ticket發送給用戶,並將用戶重定向到系統1(注意,此時會帶上P-ticket)。

5.系統1接收到帶有P-ticket的請求後,會向認證中心發出一個請求,驗證P-ticket的有效性。

6.認證中心接收到系統1的校驗請求,將校驗結果返回給系統1。同時若驗證經過則會將映射關係(P-ticket,系統1)記錄到一個映射表中(稱該表爲「註冊系統表」,即記錄那些登陸的子系統與P-ticket的對應關係,這樣在用戶註銷的時候就能夠向相應的子系統發送請求,銷燬相應的局部session)。

7.系統1接受到認證中心的校驗結果,若校驗經過,則認爲用戶是「已登陸」,系統1在自身系統爲用戶建立一個session(局部session),並生成一個綁定該session的A-ticket,同時將映射關係(A-ticket,P-ticket)記錄到本身的一個映射表中(稱該表爲「ticket映射表」)。而後系統1將A-ticket發送給用戶,在後續用戶對系統1的訪問中,會帶上A-ticket,則能夠經過A-ticket判斷用戶是否已經登陸。

8.用戶訪問系統2,系統2發現用戶爲登陸(沒有B-ticket),跳轉到認證中心(此時對認證中心的訪問會帶上P-ticket),並帶上系統2的url做爲參數(即回調url,這樣認證後就能夠跳轉回來了)。

9.認證中心發現用戶已經登陸(由於用戶已經持有P-ticket),確認P-ticket的有效性後便可認爲用戶「已登陸」。認證中心將用戶重定向到系統2(帶上P-ticket)。

10.系統2接收到帶有P-ticket的請求後,會向認證中心發出一個請求,驗證P-ticket的有效性。

11.認證中心接收到系統2的校驗請求,將校驗結果返回給系統2。同時若驗證經過則會將映射關係(P-ticket,系統2)添加到「註冊系統表」

12.系統2接受到認證中心的校驗結果,若校驗經過,則認爲用戶是「已登陸」,系統2在自身系統爲用戶建立一個session(局部session),並生成一個綁定該session的B-ticket,同時將映射關係(A-ticket,P-ticket)記錄到本身的一個映射表中(稱該表爲「ticket映射表」)。而後系統2將B-ticket發送給用戶,在後續用戶對系統2的訪問中,會帶上B-ticket,則能夠經過B-ticket判斷用戶是否已經登陸。


註銷圖示:
註銷(徹底跨域單點登陸)

1.用戶向系統1發起註銷請求(會帶上A-ticket)。

2.系統1根據映射表「ticket映射表」,取出相應的P-ticket。系統1向認證中心發起註銷請求(帶上P-ticket)。

3.認證中心接收到註銷請求後,驗證P-ticket的有效性。若P-ticket有效,則銷燬本地的全局session(根據P-ticket)。認證中心從「註冊系統表」中查找出與P-ticket相關的全部系統,向全部相關的系統發送註銷局部會話請求。

4.系統2接收到認證中心的「註銷局部會話」請求,根據P-ticket從「ticket映射表」中取出相應的B-ticket,根據B-ticket銷燬本地局部會話。

5.系統1接收到認證中心的「註銷局部會話」請求,根據P-ticket從「ticket映射表」中取出相應的A-ticket,根據A-ticket銷燬本地局部會話。


值得注意的地方:1.在上面的實現中,咱們能夠看到P-ticket是須要在各個端傳遞的,故出於安全考慮,應該對P-ticket作一些安全性處理,如加密等。

相關文章
相關標籤/搜索