一、單點登入的介紹
單點登入(Single Sign On),簡稱為 SSO,是目前比較流行的企業業務整合的解決方案之一。SSO的定義是在多個應用系統中,使用者只需要登入一次就可以訪問所有相互信任的應用系統。
例如:百度旗下有很多的產品,比如百度貼吧、百度知道、百度文庫等,只要登入百度賬號,在任何一個地方都是已登入狀態,不需要重新登入。
當用戶第一次訪問應用系統的時候,因為還沒有登入,會被引導到認證系統中進行登入;根據使用者提供的登入資訊,認證系統進行身份校驗,如果通過校驗,應該返回給使用者一個認證的憑據--ticket;使用者再訪問別的應用的時候,就會將這個ticket帶上,作為自己認證的憑據,應用系統接受到請求之後會把ticket送到認證系統進行校驗,檢查ticket的合法性。如果通過校驗,使用者就可以在不用再次登入的情況下訪問應用系統2和應用系統3了。
、
要實現SSO,需要以下主要的功能:
所有應用系統共享一個身份認證系統。 統一的認證系統是SSO的前提之一。認證系統的主要功能是將使用者的登入資訊和使用者資訊庫相比較,對使用者進行登入認證;認證成功後,認證系統應該生成統一的認證標誌(ticket),返還給使用者。另外,認證系統還應該對ticket進行效驗,判斷其有效性。所有應用系統能夠識別和提取ticket資訊 要實現SSO的功能,讓使用者只登入一次,就必須讓應用系統能夠識別已經登入過的使用者。應用系統應該能對ticket進行識別和提取,通過與認證系統的通訊,能自動判斷當前使用者是否登入過,從而完成單點登入的功能。二、單點登入技術實現機制
在說單點登入(SSO)的技術實現之前,我們先說一說普通的登入認證機制。
如上圖所示,我們在瀏覽器(Browser)中訪問一個應用,這個應用需要登入,我們填寫完使用者名稱和密碼後,完成登入認證。這時,我們在這個使用者的session中標記登入狀態為yes(已登入),同時在瀏覽器(Browser)中寫入Cookie,這個Cookie是這個使用者的唯一標識。下次我們再訪問這個應用的時候,請求中會帶上這個Cookie,服務端會根據這個Cookie找到對應的session,通過session來判斷這個使用者是否登入。如果不做特殊配置,這個Cookie的名字叫做jsessionid,值在服務端(server)是唯一的。
1、同域下的單點登入
一個企業一般情況下只有一個域名,通過二級域名區分不同的系統。比如我們有個域名叫做:a.com,同時有兩個業務系統分別為:app1.a.com和app2.a.com。我們要做單點登入(SSO),需要一個登入系統,叫做:sso.a.com。
我們只要在sso.a.com登入,app1.a.com和app2.a.com就也登入了。通過上面的登陸認證機制,我們可以知道,在sso.a.com中登入了,其實是在sso.a.com的服務端的session中記錄了登入狀態,同時在瀏覽器端(Browser)的sso.a.com下寫入了Cookie。那麼我們怎麼才能讓app1.a.com和app2.a.com登入呢?這裡有兩個問題:
Cookie是不能跨域的,我們Cookie的domain屬性是sso.a.com,在給app1.a.com和app2.a.com傳送請求是帶不上的。sso、app1和app2是不同的應用,它們的session存在自己的應用內,是不共享的。
那麼我們如何解決這兩個問題呢?針對第一個問題,sso登入以後,可以將Cookie的域設定為頂域,即.a.com,這樣所有子域的系統都可以訪問到頂域的Cookie。我們在設定Cookie時,只能設定頂域和自己的域,不能設定其他的域。比如:我們不能在自己的系統中給baidu.com的域設定Cookie。
Cookie的問題解決了,我們再來看看session的問題。我們在sso系統登入了,這時再訪問app1,Cookie也帶到了app1的服務端(Server),app1的服務端怎麼找到這個Cookie對應的Session呢?這裡就要把3個系統的Session共享,如圖所示。共享Session的解決方案有很多,例如:Spring-Session。這樣第2個問題也解決了。
同域下的單點登入就實現了,但這還不是真正的單點登入。
2、不同域下的單點登入
同域下的單點登入是巧用了Cookie頂域的特性。如果是不同域呢?不同域之間Cookie是不共享的,怎麼辦?
這裡我們就要說一說CAS流程了,這個流程是單點登入的標準流程。
上圖是CAS官網上的標準流程,具體流程如下:
使用者訪問app系統,app系統是需要登入的,但使用者現在沒有登入。跳轉到CAS server,即SSO登入系統,以後圖中的CAS Server我們統一叫做SSO系統。 SSO系統也沒有登入,彈出使用者登入頁。使用者填寫使用者名稱、密碼,SSO系統進行認證後,將登入狀態寫入SSO的session,瀏覽器(Browser)中寫入SSO域下的Cookie。SSO系統登入完成後會生成一個ST(Service Ticket),然後跳轉到app系統,同時將ST作為引數傳遞給app系統。app系統拿到ST後,從後臺向SSO傳送請求,驗證ST是否有效。驗證通過後,app系統將登入狀態寫入session並設定app域下的Cookie。至此,跨域單點登入就完成了。以後我們再訪問app系統時,app就是登入的。接下來,我們再看看訪問app2系統時的流程。
使用者訪問app2系統,app2系統沒有登入,跳轉到SSO。由於SSO已經登入了,不需要重新登入認證。SSO生成ST,瀏覽器跳轉到app2系統,並將ST作為引數傳遞給app2。app2拿到ST,後臺訪問SSO,驗證ST是否有效。驗證成功後,app2將登入狀態寫入session,並在app2域下寫入Cookie。這樣,app2系統不需要走登入流程,就已經是登入了。SSO,app和app2在不同的域,它們之間的session不共享也是沒問題的。
有的同學問我,SSO系統登入後,跳回原業務系統時,帶了個引數ST,業務系統還要拿ST再次訪問SSO進行驗證,覺得這個步驟有點多餘。他想SSO登入認證通過後,通過回撥地址將使用者資訊返回給原業務系統,原業務系統直接設定登入狀態,這樣流程簡單,也完成了登入,不是很好嗎?
其實這樣問題時很嚴重的,如果我在SSO沒有登入,而是直接在瀏覽器中敲入回撥的地址,並帶上偽造的使用者資訊,是不是業務系統也認為登入了呢?這是很可怕的。
總結單點登入(SSO)的所有流程都介紹完了,原理大家都清楚了。總結一下單點登入要做的事情:
單點登入(SSO系統)是保障各業務系統的使用者資源的安全 。各個業務系統獲得的資訊是,這個使用者能不能訪問我的資源。單點登入,資源都在各個業務系統這邊,不在SSO那一方。 使用者在給SSO伺服器提供了使用者名稱密碼後,作為業務系統並不知道這件事。 SSO隨便給業務系統一個ST,那麼業務系統是不能確定這個ST是使用者偽造的,還是真的有效,所以要拿著這個ST去SSO伺服器再問一下,這個使用者給我的ST是否有效,是有效的我才能讓這個使用者訪問。三、單點登入優缺點
優點
1)提高使用者的效率。
使用者不再被多次登入困擾,也不需要記住多個 ID 和密碼。另外,使用者忘記密碼並求助於支援人員的情況也會減少。
2)提高開發人員的效率。
SSO 為開發人員提供了一個通用的身份驗證框架。實際上,如果 SSO 機制是獨立的,那麼開發人員就完全不需要為身份驗證操心。他們可以假設,只要對應用程式的請求附帶一個使用者名稱,身份驗證就已經完成了。
3)簡化管理。
如果應用程式加入了單點登入協議,管理使用者帳號的負擔就會減輕。簡化的程度取決於應用程式,因為 SSO 只處理身份驗證。所以,應用程式可能仍然需要設定使用者的屬性(比如訪問特權)。
缺點
1)不利於重構
因為涉及到的系統很多,要重構必須要相容所有的系統,可能很耗時。
2) 無人看守桌面
因為只需要登入一次,所有的授權的應用系統都可以訪問,可能導致一些很重要的資訊洩露。