在結構設計上復用性是一個很重要的特征,昨天半夜我發的系統地非侵入性也是很重要的,有同志邀我看看他的SSO系統,不過看后都我覺得不甚滿意,如果要服用的話需要把分散的代碼一點點摳出來,然后經過反復的修改調試后才能在新的系統中使用,那位老兄的SSO系統功能可能確實強大,而且還用了新技術,不過在復用性上我看還是沒有擺脫集成上的痛苦,作過系統集成的同學們肯定對此深有感觸。
昨天才批判了很多同學寫東西語焉不詳,結果回頭就自己給了自己一耳巴子,上幾篇關于SSO的描述都不夠詳細,于是這里在手把手系列里我們來一起看看如何設計一個高度可服用的SSO模塊,這里我們假設所有的站點都使用.NET,因為成熟的SSO需要和采用各種不同技術的站點之間實現SSO,于是有JAVA,PHP,COM+,.NET多種形式的PSO模塊。這里我們精力有限,所以先假設都用.NET,如果你會JAVA也可以自己用java來實現PSO。
一般來說單點認證都需要兩端來完成,在認證中心端的我們稱之為SSO,在網站端的模塊我們稱之為PSO。兩個模塊之間采用二次重定向技術來實現同步兩端票據的方式來實現單點登陸
首先我們就來看看這兩個模塊式如何配合來完成單點認證的
第一個場景是用戶首先訪問認證中心登陸再去進入成員網站的情況:

首先是登陸后產生一個SSO的票據,這個票據是最重要的,因為它是決定用戶是否登陸的關鍵。這個票據可以是Cookie,也可以是Session,我比較傾向于Cookie,因為現在有3DES加密,加密后篡改Cookie幾乎成為不可能,所以無論是對于服務器負擔來說還是安全性都是Cookie比較好,可能人認為萬一不支持Cookie呢,不過我想Demo應該沒問題吧,大不了我設計成兩個都支持:},
PS,為什么不用非對稱加密?其實那個效率不高,3DES的安全性已經足夠了,至少現在還沒有人宣稱能破解
在登陸后就可以通知用戶你已經登陸了,現在你可以去訪問成員站點了,這個時候用戶點擊了成員站點的URL,進去了,這個時候首先就需要接受PSO組件的盤查,你有沒有PSO的票據呢?很顯然是沒有的,所以這個時候請求就被Redirect回了認證中心,認證中心檢查用戶已經有了SSO的票據了,認為用戶已經登錄了,就把用戶的SSO票據附加在URL后邊然后Redirect回成員站點,成員站點的PSO這個時候獲取到了SSO票據,于是知道了用戶已經在認證端登錄了,于是就創建一個PSO票據,然后返回給用戶他所請求的內容。所以我們來看看其實PSO的邏輯更加復雜一點。
SSO的邏輯:
PSO的邏輯:
這里我們可以看到其實兩個模塊的功能都不算復雜,這里存在幾個現實的問題,第一個是加密問題,票據需要加密,傳輸的URL也需要加密。
還有一個就是上一次我上篇文章里說的,在SSO把票據通過URL發送給PSO的時候,如果我們能夠截獲這個URL,不管他加沒有加密,在下一次我們直接用這個URL去訪問站點的時候因為已經包含SSO票據了,所以PSO會認為已經登陸了而直接產生PSO票據然后就讓用戶進去了,這顯然是一個漏洞。所以呢,我們需要在這里給這個URL加一點鹽值(所謂鹽值其實就是加點料),我們通過在URL里加入時間戳來讓這個URL具備時間限制,這個樣子URL具備失效期,過了這個時間即使截獲到了這個URL也完全沒有作用了。