我們在實現業務中經常會碰到多個系統各自有各自的用戶登錄系統,而且這些系統是各自運行在各自的域下,所以要實現這些系統用戶的單點登錄就是個問題了,所以自己想了一個方案希望看看是否可行。
1.sso站點必須是單獨一個站點。
我把sso單獨設立一下站點,這個站點可以單獨一個域名,主要存放各個系統的用戶信息及登錄的cookie信息。
2.保證各個系統的用戶數據一致性和獨立性。
各個系統擁有自己的用戶數據表相互獨立。每一個系統的CUD(創建,更新,刪除)時都會觸發其它系統的CUD。那么這里有個問題也會出現:各個系統登錄無非就驗證用戶名和密碼,所以就得保證各個系統的至少登錄名、密碼的一致性,可是各個系統可能處理密碼時都有各自的方法,有的系統直接使用明文,有的系統使用md5或者其它加密方式。這時在沒完成單點登錄構架時的各個系統中對那些不可逆密碼的數據處理就基本不可能了。我想到這種最好處理方法是所有密碼加密只能遵循其中一種不可逆的加密了,那些可逆或者明文的密碼都可以轉成這種密碼處理方式,這樣數據就可以同步了,當然如果出現兩種不一樣且不可逆的密碼時貌似就想不到啥解決方案了。
3.當某一用戶進入某一系統,且他還未完成任何一個系統登錄的處理。
用戶輸入某一個系統的網址進來,該系統就必須檢測當前這個操作的是游客還是系統用戶,其實如果不是多系統單點登錄的話,就這一個系統也是會通過cookie、session等之類東西去檢測游客還是系統用戶,但只局限於此站點的檢測。因為我知道我壓根就沒有此站點登錄過,所以就得去其它系統中檢測我是否有登錄過,通過檢測我還是沒有在任何地方登錄過,所以我的登錄只是一名游客。
根據以上的需求,應該是這樣去處理:
輸入網站進入某一系統的其實一個頁面,該頁面(我這里把頁面=行為處理的Handler)需要做的事是:進入頁面構造時就redirect到了sso站點且redirect時必須附上returnUrl,因為sso站點處理后需要再次回調到用戶進入某一系統的頁面,總不至於停留在sso站點,因為用戶都不知道有sso站點這回事。redirect到sso站點后,sso站點頁面第一步只需要看看sso站點是否有登錄的cookie信息,因為用戶根本就沒登錄,所以肯定就不存在這個cookie值了,所以說明在其它系統我們沒登錄過,那么就得告訴用戶進入的某一系統沒有登錄了,根據returnUrl並附帶一個空的Token(如Token=$,$代表空)跳轉到用戶原來要進入的某一系統的頁面,其實這時用戶進入的還是原來的頁面只是該頁面附帶了一個空的Token。頁面看到了有一個Token參數,所以頁面知道已經去過了sso站點檢測且證明該用戶在其它系統也是不存在登錄的。要注意的是這里若不到Token,系統就死循環了哦!
4.用戶在所有系統都未登錄時,用戶進入的某一系統完成用戶登錄的處理。
這里的登錄有以下步驟進行處理:
1).某一系統根據用戶登錄的用戶名、密碼以后在自已對應的數據庫中驗證是否正確,正確說明登錄成功了。
2).系統登錄成功后就必須反饋給sso站點,那么這時應該怎么反饋呢?我的想法還是通過sso站點回調的方式去處理。某一系統登錄成功以后其實根據需要得跳轉到相關指定頁面,這時攔截跳轉頁面並記錄url並做為sso站點頁面的returnUrl,sso站點處理授權登錄的頁面接受的參數不能只有一個returnUrl,至少還得告訴該頁面是哪個用戶進行登錄了,否則去sso站點驗證后怎么知道哪個用戶登錄了,但僅僅是一個用戶名參數夠了嗎?我是覺得不夠,這樣也太不安全了,真那樣我只要通過這個頁面+用戶名不是完成登錄了?
本來我是這么想的:
sso站點授權頁面得到三個參數(用戶名,密碼,returnUrl) ,sso站點需要向某一系統的用戶數據表(各個系統的用戶數據已經保持一致同步了)再次驗證,在各系統數據同步正常的情況下驗證其實肯定是成功的狀態,成功后取出用戶相關信息保存的緩存中,用戶信息中也附帶一個token值(唯一的),然后再在sso站點中生成一個cookie(存放的是一個token值), 同時這里的cookie和緩存信息失效時間需要設定一致。
后來是這么想的:
sso站點授權頁面得到還只是兩個參數(加密的用戶名,returnUrl),當然這種加密是可逆的加密,但加密的key是會定時變化的,發送的這個加密的用戶名,sso站點根據key解密得到用戶名和生成一個token值(唯一的)存入緩存,然后再在sso站點中生成一個cookie(存放的是一個token值), 同時這里的cookie和緩存信息失效時間需要設定一致。
5.用戶已經在某一系統中登錄,但現在去了另外一系統,在該系統中還未完成授權。
因為現在去的這個系統其實還未完成登錄,那么要得遵循3的步驟,構造去sso站點附帶一個returnUrl,驗證到了在sso站點有cookie信息,取出這個cookie值得到token,然后回調至已附帶token參數的returnUrl頁面,該頁面判斷token值存在后進入構造后的下步處理,該處理知道有token值后調用sso站點的api(webservice或者restful請求方式)得到用戶名,根據這個名再從數據庫中得到密碼,並完成登錄操作。
6.用戶在某一系統登錄后,每次需登錄驗證的頁面請求會間歇性的向sso站點更改token值並完成延長cookie及緩存會話時間。
用戶在長時間未操作時,可能訪問的系統和sso系統會話結束時間不一致,這里我們只要保證sso或者系統會話時間只要一個未結束,就還會存在登錄狀態的。只有兩方都沒有會話時間的情況時才會跳轉到登錄頁面要求登錄。
7.用戶在某一系統登錄后,點擊了該系統的退出
用戶點擊退出后,應實現某一個站點點退出所有站點全部退出功能。各站點可擁有自己的退出功能,某站點退出后再回調清除sso站點的緩存和一個sso所有站點退出頁面,而sso站點應用應有一個退出登錄的功能頁面(聚集所有站點退出功能,批量回調各個實現退出),該功能可實現所有站點的退出
