Java單點登錄學習心得
阿新 • • 發佈:2019-01-28
pan 登錄失敗 cnblogs png 生成 封裝 思路 任務管理器 方法
什麽是單點登錄?
SSO(Single Sign On)單點登錄是實現多個系統之間統一登錄的驗證系統,簡單來說就是:有A,B,C三個系統,在A處登錄過後,再訪問B系統,B系統就已經處於了登錄狀態,C系統也是一樣。舉個生活中栗子:你同時打開天貓和淘寶,都進入login界面,都要求你登錄的,現在你在淘寶處登錄後,直接在天貓處刷新,你會發現,你已經登錄了,而且就是你在淘寶上登錄的用戶。說明他們實現了SSO,並且持有相同的信息。
整體流程
編碼實現(結尾貼代碼)
1.工程創建
- 創建一個JAVA模塊,在這個模塊下創建3個web應用,其中一個當作單點登錄服務器sso_server,另外2個分別當作2個應用app1和app2
- 創建基本目錄和包結構,並導入依賴的jar包
- 配置不同端口的tomcat服務器
2.實現思路
- 第一次訪問App1或App2登錄受限的頁面時,使用過濾器將其全部重定向到單點登錄服務器的登錄頁面,並帶上本應用域名標識來源(以下假設請求來源app1,默認登錄成功是/index)
- 單點登錄服務器重寫LoginServlet中init和service方法,在init方法中獲取在xml中配置的需要實現單點登錄服務器的域名信息,用逗號分割
- service方法用來處理請求
- 當請求是/ssoLogin,也就是app1重定向過來的,將請求轉發到/login.jsp,顯示登錄頁面
- 當請求是/login,也就是用戶提交表單,模擬登錄,登錄失敗,轉發到/login.jsp,轉發前往request作用域添加請求來源信息,然後添加到登錄表單隱藏域
- 登錄成功,直接重定向到對應來源的應用登錄成功頁面--帶上登錄標識UUID生成或者其他方式以及其他應用地址(需要進行字符串替換,過濾掉自己)
- 然後請求回到了app1下的/index,經過過濾器的驗證(後面這裏會修改)交給app1的MainServlet處理,重寫service方法,用來處理請求
- 當請求是/index,說明是單點登錄過來的,同時帶上了登錄標識flag和其他應用域名信息domains(逗號分割的字符串),這裏將其拆分,用一個線程池去並發通知其他應用執行設置Cookies操作,帶上操作標識和登錄標識,通知完回到本應用默認首頁
- 這裏封裝了一個方法syncCookies(server, flag, "setCookie");
- 別的應用也需要調用setCookies方法,所以要配置相關訪問路徑做相應處理
- 這個時候有Cookies了,需要考慮Cookies存在的情況登錄判斷,修改app1中的過濾器
- 從Cookies中獲取登錄標識,判斷是否超時
- 重新獲取登錄標識,沒有重定向到sso服務器的登錄
- 有則重新設置cookies,‘:‘帶上過期時間用於下次判斷
- cookies中不存在登錄標識.請求參數也沒有,重定向到sso服務器的登錄頁
- cookies中不存在登錄標識.請求參數中有,重新設置cookies帶上過期時間
- 退出實現
- 當請求是/ssoLogout,,使用過濾器將其全部重定向到單點登錄服務器的退出,並帶上本應用域名標識來源(應該在帶上用戶標識表明是那個用戶,這裏簡化不作處理)
- 單點登錄服務器service方法處理退出請求,重定向到來源應用的退出,並帶上其他應用域名信息用於通知
- 然後回到了app1下的MainServlet中service方法處理請求
- 退出刪除cookies中的登錄標識(這裏設置一個新的cookies為空,有效期為0,覆蓋掉原來的cookies),然後調用一個線程池去並發通知其他應用執行移除Cookies操作,帶上操作標識和登錄標識,通知完回到本應用退出登錄頁,
- syncCookies(server, "", "removeCookie");
- 別的應用也需要調用removeCookie方法,所以要配置相關訪問路徑做相應處理
總結
- 單點登錄服務器需要實現的操作
- 配置需要單點登錄的應用域名信息
- 登錄頁/ssoLogin
- 登錄提交/login
- 成功重定向到對應來源的應用登錄成功頁面--帶上登錄標識以及其他應用地址
- 失敗 往request作用域添加請求來源信息添加到隱藏域中用於下次判斷,轉發到登錄頁
- 退出登錄/ssoLogout
- 重定向到來源應用的退出,並帶上其他應用域名信息用於通知
- 各應用服務器需要實現的操作(app1和app2代碼基本一樣只是配置本應用域名不同)
- 過濾器Filter
- 配置sso_server地址和本應用地址,過濾全部請求
- 退出請求,則重定向到sso_server服務器的退出
- 判斷cookies有沒有登錄標識,是否過期,
- cookies有但過期了,
- 請求參數中無登錄標識,重定向到sso_server服務器的登錄頁
- 請求參數中有登錄標識,則重新設置cookies和過期時間
- cookies沒有
- 請求參數中無登錄標識,重定向到sso_server服務器的登錄頁
- 請求參數中有登錄標識,則重新設置cookies和過期時間
- cookies有但過期了,
- 過濾器Filter
- Servlet
- 重寫service方法處理請求
- sso_server認證成功回到/index請求(app1默認首頁),如果是第一次登錄,會從請求參數中獲取登錄標識和需要通知的其他應用地址,將地址拆分,並發通知其他應用設置cookies信息
- 可能是你通知我,也可能是我通知你,所以本應用也要實現setCookies操作
- 如果是退出請求/logout,同理也需要通知其他應用刪除cookies
- 本應用也要實現removeCookies操作
遇到的問題
1.IDEA調試無法啟動報錯Unable to open debugger port (127.0.0.1:51554): java.net.SocketException "socket closed"
暴力解決方法:幹掉所有的java進程,重新啟動即可,任務管理器結束掉所有的 java.exe進程
2. 線程池的創建方式,在使用阿裏巴巴代碼規範插件檢查時,發現並不推薦使用
private ExecutorService service = Executors.newFixedThreadPool(10); //提示信息:不允許使用 Executors 去創建,而是通過 ThreadPoolExecutor 的方式,這樣的處理方式讓寫的同學更加明確線程池的運行規則,規避資源耗盡的風險
解決方案:http://www.cnblogs.com/javanoob/p/threadpool.html
代碼下載地址:sso.rar
Java單點登錄學習心得