2013-08-18 147 views
3

根據Java EE標準,Tomcat允許請求通過兩種方式指定其現有會話ID:1)通過cookie; 2)通過「路徑參數」(不是常規參數;路徑參數的格式爲http://host/path/file.ext;jsessionid=xxx?a=b&c=d... - 注意「;」以及查詢字符串僅在路徑參數後面開始的事實)。我想要的是將請求中的會話ID作爲REGULAR參數傳遞給「?」後面的查詢字符串,如http://host/path/file.ext?jsessionid=xxx覆蓋Tomcat從請求中獲取sessionid的方法

當請求到達我可以攔截它並更改容器確定會話ID的方式(例如在Filter或Servlet中)時,就太遲了。我想改變的行爲是在來自客戶端的請求的初始處理中。我想避免做的是改變Coyote或Tomcat代碼並自己重建Tomcat,原因很明顯。我想要做的是重寫相應的代碼並配置Tomcat以使用該代碼來確定請求的會話ID。這似乎不可能,但我希望我錯了。

我知道以這種方式獲取會話ID是非標準的;我知道使用cookie或路徑參數是跟蹤會話狀態的最佳方法;我知道將會話ID放在實際的查詢字符串中會帶來潛在的問題。無論如何,我需要這樣做。

運行Tomcat 7,順便說一句。

+0

你似乎有一個很好的理由來做到這一點。你可以與我們分享嗎? –

+0

@JB Nizet - 當然。我們對我們的用戶說,「我們不使用cookies,期限。」我們的應用程序與隱私相關,可以說這是一件好事。現在,會話cookie當然與長壽命的cookie不同,但是許多用戶失去了這種區別。所以這是關於隱私的認識,真的。無論如何,這意味着我需要通過URL保持會話(具有各種防範劫持,obv的保護措施)。但是,當提供用戶可以保存的內容時(某些瀏覽器將jsessionid作爲文件名的一部分),「路徑參數」格式會混淆某些瀏覽器。 –

+0

@Will Hartung - 非常有幫助,謝謝。是的,你是正確的,我們必須小心從生命週期早期的請求中解析params。由於這個原因,我不會使用'getParameter()';我只是解析出來的查詢字符串。 (其中,正如你所指出的,這意味着我的session id參數不能被POST,但這沒關係,因爲POST URL仍然可以添加查詢字符串。) –

回答

1

最簡單的方法是從源代碼構建Tomcat,並破解CoyoteAdapter.java類。

這是代碼所在的位置,但它不在代碼的易擴展部分,您只需插入一點代碼即可截取這部分請求管道。

你可以聰明地實現你自己的連接器,它依賴於你自己的CoyoteAdapter,而不是隻是將它「黑到位」,但最終你仍然有一個維護更新等問題的維護問題。

您還需要小心,因爲通常情況下,請求參數不會「解析」,直到有人要求爲止,並且通常在實際用戶代碼之前不會完成(我不相信它是在管道之前完成的擊中用戶代碼)。

這很重要,因爲雖然對於GET,參數解析是從請求標頭完成的,對於POST,它是基於內容。如果你詢問參數的請求,它不關心它是POST還是GET,並會自動「做正確的事情」。

這意味着如果要求從POST的請求參數,所述管道將消耗的用戶應用程序代碼之前的輸入流(其開始於所述請求有效載荷指向,頭之後)。取決於用例,但有些應用程序需要原始流,因此您必須謹慎使用內置的請求參數邏輯,而不是對原始URL本身進行操作。

你也可以通過一個簡單的過濾器逃避這一點,然後你可以將HttpServletRequest強制轉換爲底層的Tomcat實現(此時誰的名字不在我身邊),然後調用「setSessionID」代碼那。不知道,如果在加工週期中這太遲了,那很可能是。

所以,這是可以做到的,而只是現在看來,但不通過任何延伸真的規定手段。官方的方法是克隆Tomcat連接打電話給你自己的CoyoteAdapter的版本,並配置在server.xml。但是如果你願意維護你自己的tomcat版本,直接黑客攻擊CoyoteAdapter會容易得多。