1. 程式人生 > >SSO單點登入教程(二)單點登入流程分析

SSO單點登入教程(二)單點登入流程分析

作者:藍雄威,叩丁狼教育高階講師。原創文章,轉載請註明出處。

一、簡介

單點登入(Single Sign On),簡稱為 SSO,是目前比較流行的企業業務整合的解決方案之一。SSO的定義是在多個應用系統中,使用者只需要登入一次就可以訪問所有相互信任的應用系統。

二、應用場景

如公司有多個系統,分別OA系統、CRM系統、財務管理系統、裝置管理系統等,總不能訪問每個系統都要登入一遍吧,使用者會瘋掉的,應該我們認證一遍,其他系統即可訪問。網上很多專案都在使用SSO單點登入,比如天貓,淘寶,CSDN,部落格園.

三、流程分析

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

單點登入原理

步驟分析:
1.使用者通過瀏覽器訪問WMS(進銷存)系統的受保護資源,訪問地址為:http://www.wms.com/index,該資源為受保護資源,所以需要先判斷一下使用者登陸了.(是否有區域性會話)
2.WMS系統發現使用者並沒有登陸,此時重定向到統一認證中心,並把請求地址作為引數傳過去.
3.此時瀏覽器發出一個請求檢視統一認證中心是否已經登入了?發現使用者並沒有登入,轉發到統一認證中心的登陸頁面.
4.使用者輸入賬號密碼.
5.統一認證中心認證使用者資訊.如果認證成功,建立瀏覽器與統一認證中心之間的會話,稱為全域性會話.同時建立授權令牌.重定向到WMS之前請求的地址,並把令牌資訊帶上.http://www.wms.com/index?token=4KLdkEo9k7CXfle4


6.WMS拿到令牌後,需要到統一認證中心檢驗令牌是否有效.
7.統一認證中心認證令牌有效,返回有效,並註冊WMS的系統地址.
8.WMS得到統一認證中心的響應,知道令牌是有效的,建立區域性的會話.並放行請求
9.WMS後續的請求訪問的時候,發現WMS系統中有區域性的會話,直接就放行了.
10.使用者訪問CRM(客戶關係管理)系統的受保護資源,訪問地址為:http://www.crm.com/index
11.WMS系統發現使用者並沒有登陸(沒有區域性會話),此時重定向到統一認證中心,並把請求地址作為引數傳過去.
12.此時瀏覽器發出一個請求檢視統一認證中心是否已經登入了?發現使用者已經登入了,從會話中取出令牌,重定向到CRM系統,並把令牌帶上.http://www.crm.com/index?token=SrEpDwAQlHLdkJIE

13.CRM拿到令牌後,需要到統一認證中心檢驗令牌是否有效.
14.統一認證中心認證令牌有效,返回有效,並註冊CRM的系統地址.
15.CRM得到統一認證中心的響應,知道令牌是有效的,建立區域性的會話.並放行請求
16.WMS後續的請求訪問的時候,發現WMS系統中有區域性的會話,直接就放行了.

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

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

同學們花20分鐘時間把這張流程圖好好理解理解.

四、系統中的Cookie和Session儲存圖解

這個執行流程裡面很關鍵的點是統一認證中心和各個子系統的cookie和session是如何儲存的?如果把裡面的cookie和session搞清楚了,單點登入原理基本已經理解90%了.
下面我們就通過圖解的方式來看看,上面的訪問流程中每個系統中的cookie和session是怎麼儲存的.

注意:以下圖解是方便同學們理解所畫的,可能有細節和真實情況有細微出入.但是不影響理解,希望不要鑽牛角尖,能看懂即可.

圖01:下圖中,我們有三個伺服器,分別是統一認證中心:www.sso.com,CRM客戶關係管理系統:www.crm.com,WMS經銷存系統:www.wms.com.每個系統都有一個區域儲存session的地方,同學們可以暫時理解就是有個map來儲存session物件.這個map的key存的是session的id,value存的是session物件.
在瀏覽器本地會有三個目錄儲存對應域名的cookie.比如:訪問www.crm.com的時候會在瀏覽器本地的crm.com目錄找對應的cookie,並在請求的時候把這個目錄下的cookie請求一併的帶到伺服器.(這個動作是瀏覽器完成的,不需要使用者操作.),而且www.crm.com伺服器響應cookie的時候會寫入到瀏覽器本地的crm.com目錄.
目前我們還沒發起請求,所以所有的內容都是空的.
單點登入01

圖02:第一次訪問http://www.crm.com/employee,首先會在瀏覽器本地的crm.com目錄中尋找是否有對應的cookie,如果可以沒有說明目前瀏覽器和伺服器之間還沒有建立會話,也就是說沒有區域性的會話.
這時候我們需要重定向到統一認證中心,檢視是否有全域性會話(如果有全域性會話說明有其他系統已經登入了).
需要把請求訪問的地址作為引數傳遞過去,因為待會得回撥這個地址.
具體程式碼如下:

String url = "http://www.sso.com/checkLogin?redirectUrl=http://www.crm.com/employee";
response.sendRedirect(url);

單點登入02
圖03:因為重定向,瀏覽器會呼叫統一認證www.sso.com中的checkLogin方法,檢視是否有全域性的會話.
這時候是請求http://www.sso.com/checkLogin地址,瀏覽器會在本地的sso.com目錄找對應的cookie資訊並在請求的時候一併得帶到伺服器.
但是這次的請求,瀏覽器本地目錄sso.com中並沒有cookie資訊,意味瀏覽器和統一認證中心之間還沒有建立會話.
沒有會話說明並沒有登入.此時要轉發到統一認證中心的登陸頁面.
需要把位址列中的redirectUrl從位址列中獲取出來.

request.getParamter("redirectUrl");

並把這個引數放入到request域中.因為在登陸成功之後要跳轉到使用者之前訪問的地址.

單點登入03
圖04:轉發到統一認證中的登陸頁面.
單點登入04
圖05:使用者在統一認證中心的登陸頁面輸入了賬戶名和密碼之後.統一認證中心伺服器對使用者資訊進行認證.認證通過需要做這幾個事情:
1.建立令牌,後續操作中得發給子系統,相當於間接授權.
2.建立全域性會話,並把令牌儲存到全域性會話中.
3.把令牌資訊儲存到資料庫中的t_token表中.主要是後續客戶端校驗token的有效性需要查詢這種表.
4.重定向到之前使用者請求的地址redirectUrl.並把令牌發給該子系統.http://www.crm.com/employee?token=VcnVMguCDWJX5zHa

統一認證中心會把session的id(我們也稱為JSESSIONID)響應到客戶端瀏覽器本地目錄sso.com的cookie檔案中.儲存的結構是key/value格式.key是固定的字串JSESSIONID,value是伺服器sessionid的字串.
在後續訪問www.sso.com的時候都會帶上這個JSESSIONID

單點登入05
圖06:因為重定向,瀏覽器訪問http://www.crm.com/employee?token=VcnVMguCDWJX5zHa,此時瀏覽器會在本地的crm.com把所有的cookie一併的帶上.
但是本地的crm.com目錄中沒有內容,說明瀏覽器還沒有和CRM系統建立會話,說明沒有區域性會話.
但是這次的請求中包含了token令牌的資訊.
但是token是直接拼接在位址列上的,存在被偽造的可能性.所以我們需要對token令牌做有效性的校驗.

單點登入06
圖07:CRM系統在接受到令牌token資訊之後,需要去統一認證中心中校驗令牌資訊是否有效.
我們使用HttpUrlConnection傳送http請求http://www.sso.com/verify?token=VcnVMguCDWJX5zHa
統一認證中心接受到這個請求後,拿到令牌token對應的值,在資料庫表t_token中查詢是否有這條記錄.如果能找到說明這個令牌是統一認證中心發放的,返回true給呼叫者.
如果找不到,說明不是統一認證中心產生的,我們就該返回false給呼叫者.

單點登入07
圖08:CRM系統傳送的校驗請求之後,統一認證中心返回true的結果.說明令牌是有效的.此時需要做這幾件事情:
1.建立區域性的會話,並且標記這個會話已登入,設定isLogin=true
2.放行該次的請求.
伺服器會把session的id響應到客戶端,儲存在瀏覽器本地目錄crm.com目錄的cookie檔案中.在後續訪問www.crm.com的域名的時候會把該目錄下的cookie資訊一併帶上.

到這一步其實我們單個系統的登陸就已經完成了.

單點登入08
圖09:後續的請求.比如請求http://www.crm.com/department,首先根據請求的域名在本地crm.com目錄中找到對應的cookie資訊,在請求的時候會把這個JSESSIONID一併的帶上,通過這個JSESSIONID可以找到服務中屬於該瀏覽器的會話物件,並檢視isLogin屬性,如果為true,就直接放行該次的請求.

單點登入09
圖10:此時我們訪問http://www.wms.com/orderBill地址,瀏覽器根據域名會在本地的wms.com目錄中把cookie資訊在請求的時候一併帶上,但是並沒有cookie資訊,說明瀏覽器還沒有和WMS系統建立會話.
WMS沒有區域性會話,我們就要重定向到統一認證中心的checkLogin方法,檢視是否有全域性的會話(是否有其他的系統登陸了).

單點登入10
圖11:因為重定向的關係,瀏覽器傳送請求:
http://www.sso.com/checkLogin?redirectUrl=http://www.wms.com/orderBill,
校驗是否有全域性的會話,因為之前CRM已經登入了,所以有全域性會話.
需要做如事情:
1.從全域性會話中取出令牌資訊token
2.重定向到子系統之前訪問的地址,並把令牌資訊帶上.
http://www.wms.com/orderBill?token=VcnVMguCDWJX5zHa

單點登入11
圖12:因為重定向,瀏覽器傳送請求:
http://www.wms.com/orderBill?token=VcnVMguCDWJX5zHa,
瀏覽器會根據域名找本地目錄中wms.com目錄中的cookie,並在請求的時候一併的帶上.
但是並沒有cookie資訊,說明沒有區域性會話,但是有令牌資訊token.
需要到統一認證中心校驗令牌資訊token的有效性.

單點登入12
圖13:WMS系統後臺通過HttpUrlConnection的方式傳送請求,校驗token是否有效.
統一認證中心接受到請求之後,拿到token在資料庫表中檢視是否有這條記錄.並響應對應的結果資訊到WMS系統中.

單點登入13
圖14:如果認證中心的返回的校驗結果為true,說明令牌有效.那就在WMS中建立區域性的會話,並在會話中設定登陸屬性isLogin=true.
放行請求
瀏覽器會預設的被sessionid的資訊通過cookie的方式響應到瀏覽器.
瀏覽器把sessionid資訊儲存到wms.com目錄的cookie檔案中.

單點登入14
圖15:後去訪問WMS其他的受保護資源.比如:http://www.wms.com/customer,瀏覽器會在本地wms.com目錄中找cookie,並在請求的時候一併的把cookie資訊帶到伺服器.
通過JSESSIONID找到資料該瀏覽器的會話物件,檢查isLogin屬性是否為true.
放行請求.

單點登入15

當這步結束之後,在CRM系統和WMS系統中都存在區域性的會話,我們訪問這兩個系統中的任何受保護資源都會直接放行.

五、總結

同學們需要花點時間好好把上面的流程和cookie和session儲存圖解弄清楚了.程式碼實現就變得So Easy.而且開源的單點登入框架內部的實現和分析的流程基本上一致.