1. 程式人生 > >單點登入SSO的實現方式

單點登入SSO的實現方式

    這個文章我們來討論一下單點登入SSO的一些實現方式,其中包括對session和cookie的一些討論。

一、

    我們知道http協議是無狀態的協議,也就是說一次請求對應一次響應,不和這次請求的上一次和下一次請求產生關聯。那麼這樣就有一個問題,比如說,我們想實現一個購物車,我們往購物車中新增商品,每次刷新發現上一次新增的商品不見了,每次購物車裡都是這次新增的商品,前面新增的不見了。為什麼?就是因為http是無狀態協議,它壓根不知道你上一次往購物車裡添加了什麼商品。那麼我們要怎麼做才能讓購物車儲存我們前面新增的商品?那麼,我們首先要讓伺服器知道”你就是你“。

    舉個例子,比如說現在有兩個人user1,user2在往購物車裡新增東西。user1添加了A,B商品,user2添加了C,D商品,此時user1想看看自己到底往購物車裡放了什麼商品,於是user1點了一下購物車的圖示,伺服器收到請求,有個使用者要檢視購物車的商品,要把購物車的商品返回給使用者。那麼到底是返回user1的還是user2的呢?也就是說伺服器憑什麼知道這次請求來自user1(把user1的購物商品返回)呢?

    那麼是不是說我們讓我們的瀏覽器和伺服器之間通過一個憑證來通訊就可以解決。還是那上面的例子來說。比如user1登入了這個購物網站,伺服器收到了這個請求,然後告訴user1說我給你一個憑證(card1),你下次請求的時候拿著這個憑證來請求,這樣我就可以知道你是user1了。同樣的,user2也登入了這個網站,伺服器也給user2一個憑證(card2)。這時user1說想看一下我購物車裡的東西,還是點了一下購物車,不同的是,點的同時把這個card1憑證給了伺服器。此時伺服器收到請求,有個使用者要看購物車的商品,並且這個使用者有card1憑證,也就是說這個請求來自user1,那麼伺服器就很懂事的把user1的商品(A,B)返回。同樣的,user2也想看一下購物車,點了購物車的圖示,把card2憑證給伺服器,伺服器知道通過card2請求知道這次請求來自user2,也很懂事的把商品(C,D)返回。這樣一來伺服器就很清楚的知道了這次請求來自哪個使用者了。

    上面只是一個非常簡單的例子,這種讓伺服器知道這次請求來自哪個使用者的機制叫做會話機制(session)。我們用tomcat伺服器來說明。當我們訪問某個應用時,伺服器會產生一個session來保持會話,session存在與伺服器中。也就是這個請求的使用者和伺服器產生的通訊憑證。然後會設定一個cookie(cookie是屬於瀏覽器,存在硬碟中的),tomcat伺服器設定cookie的key叫”JSESSION“,value值是這個session的id。瀏覽器會把這個cookie存在瀏覽器中,下次再訪問這個應用的時候捎帶也會把這個cookie帶上,那麼當伺服器收到請求時,把這個cookie中名為”JSESSION“的id取出來。伺服器拿到這個id,就從擁有這個id的session的記憶體中取使用者的資訊,比如使用者的購物商品。下圖為請求某個java應用時的JSESSION。


    這樣一來伺服器就知道了這次請求來自哪個使用者。請求響應的過程如下圖:


二、

    接下去我們進入正題,討論一下單點登入SSO。上面那種是單應用模式,一個應用就一個登入,相對簡單。但是當我們的應用群增大,n個應用時,是不是就意味這我們每次都要分別登入這些應用。試想一下,你們公司一個有4個系統,然後你每次上班,開啟瀏覽器,首先進入系統1,登入一下,在開啟一個標籤頁,進入系統2,登入一下。。。是不是很麻煩,我們希望的是我們登入了系統1,然後再用其他系統的時候不用登入,相當於一個系統一樣。這就是單點登入SSO。下面我們討論一下單點登入的實現方式(3種)。

    方法一:利用cookie的域實現

    我們上面講到,瀏覽器會設定cookie,cookie中儲存中和伺服器通訊的session id。但是cookie是有限制的,限制就是域(網站的域名),瀏覽器傳送http請求時會去匹配,當請求的地址和cookie的域相匹配時,就會把這個cookie攜帶,不匹配就不攜帶。這樣就好辦了。比如我們有兩個系統要做單點(~~),我們我們讓這兩個系統的域名保持一致不就行了,比如A系統域名:www.myapp.A,B系統域名www.myapp.B設定的時候這是cookie的域為www.myapp,那麼訪問A,B系統時都會攜帶這個cookie,也實現了單點。以前的系統很多都是這麼做單點登入的,優點就是簡單方便,缺點就是不夠動態,首先域名要統一,其次,web伺服器還得統一,tomcat是JSESSION,php,.net伺服器就不是JSESSON了。

   方法二:增加業務應用實現

     還是有兩個系統要做單點(系統A,B),我們可以不用cookie來實現單點,增加一個系統註冊應用(系統C)。把系統A,B的功能模組全部註冊到系統C中,同時關聯賬號,系統C的 user1 關聯絡統A的 userA1,關聯絡統B的 userB1,同時登入的入口唯一,即只開放系統C的登入。那麼我們user1登入了系統C,同時要訪問系統A的某個模組,我們就可以跳轉到系統A,同時在系統A中建立userA1的session,要訪問系統B的某個模組,我們就可以跳轉到系統B,同時在系統B中建立userB1的session,這樣也可以實現單點。優點就是比較適合後臺管理類,許可權多的應用。缺點就是相對複雜。如下圖:


三、通過認證中心實現

現附上我參考的文章:認證中心SSO  (三、單點的登入 部分)

這一部分已經講的非常詳細,但是沒有練習的例子,我會在後續更新,依照這個過程寫一個例子,分享出來~

以上就是我對SSO實現的一些討論。