標籤:server struts2 bsp 出錯 使用 ref 應用 nbsp response
嗯...真的是很久沒更新了,感覺有點瓶頸了,學又學不下去,工作要用的東西又沒有難度,跳槽又沒經驗沒學曆關鍵是還不會吹也是尷尬...
無意間翻到這個部落格,又是好久不更新突然想到了還有這個東西,就發一個最近做的小工具好了
主要是在做的某系統,客戶哪裡不願意提供多連接埠,但是要部署多個應用和單點登入,於是就理所當然的用上了反向 Proxy,然後就被公司內部的sso用戶端給坑了...
SSO單點登陸一般思路應該是這樣:
重新導向到單點登入伺服器 -> 伺服器登陸成功跳回並帶上身份標識 -> 項目二次前往單點登陸伺服器校正身份並取回登陸資訊 -> 設定登陸狀態
本來是很簡單的一件事,公司以前做過也都封裝好了一個ssoclient.jar包,只要設定下過濾器繼承一個登陸成功的回調類就可以了,使用起來簡單粗暴,然而很微妙的是第一步就出了問題....公司之前寫的ssoclient.jar在第一步,未登入時過濾器內重新導向到單點登陸,而單點登陸系統要求提供一個地址參數用於登陸成功後跳回去,然而jar包內代碼卻寫死了,通過request來擷取當前伺服器的協議、地址、連接埠,拼接後重新導向了過去
然而這樣就造成了一個問題,在反向 Proxy環境下,request拿到的資料是反向 Proxy內部的內網ip和連接埠,不是外網ip和連接埠,結果就是單點登入系統跳不回去了,對應的還是struts2配置的重新導向,也有一樣的問題,而且看了下ssoclient並沒有代碼,反編譯出來還要搭建開發環境才能編譯回去,太麻煩了
搜了搜,解決方案之一是兩邊同步配置,Nginx配置轉寄真實ip和連接埠,tomcat通過外掛程式讀取並設定到request中
不過很明顯,能通過配置解決的問題....不夠好玩兒啊....喜歡搞事情的我就真的繼續搞事情了
其實思路和上面說的解決方案是一樣的,通過tomcat外掛程式配置真真實位址到request中並不通用(其他容器配置方式不一樣),而核心思路是篡改request裡的getServerPort等幾個方法返回真實的外網地址,而非反向 Proxy內部地址
那麼問題就變成了如何對request進行篡改,很明顯servlet規範裡肯定是不提供這樣的功能了,於是我想了想...可以拿Filter搞事情啊,如果我的Filter是第一個進行操作的過濾器,並且提供一個假的request和reponse給後續過濾器操作,那麼無論是struts2還是ssoclient,他們拿到的request和response都是我構造的,而非原始的
有了這個思路就好辦了,定義兩個request和response的轉寄類,對大部分真實方法進行轉寄,需要篡改的方法返回設定檔中配置的資料,然後對302重新導向重建地址(原來的相對位址如果由交給tomcat之類的容器補全路徑返回出去就會出錯,路徑會補充成反向 Proxy的內網地址),然後就完事了
試了下效果挺好的,完美騙過了ssoclient和struts2,代碼運行很正常,目前為止沒遇到什麼bug
代碼地址:https://coding.net/u/pppploi8/p/MyUtils/git/tree/master/Java/RProxyFilter
也算是在這裡順便安利下自己的工具類項目玩兒玩兒好了....順便隨便看看還有沒有人訪問這個部落格2333333
話說回來最近還在作死嘗試搞一套前後台通用的參數校正工具類,等寫好了有時間也放上來好了
[JavaEE]記錄一下反向 Proxy下SSO不能正常使用的一個坑