這個問題糾纏了我很久了,終於在今天早上解決了,感謝自己的不放棄和不斷嘗試的決心,我堅信,我可以找到解決方式!!
項目用的spring 、spring mvc、hibernate框架,關於統一錯誤頁面在開發的過程中就做過編碼,並且一直都很有效,像500,404,403等常規錯誤碼都能得到有效處理,
但是400卻不行,而且還暴露tomcat的版本信息,這是很嚴重的安全漏洞.
先按照網上的說法 將tomcat 8的conf路徑下的 catalina.properties 文件進行修改,在最后加入一句:tomcat.util.http.parser.HttpParser.requestTargetAllow=|{}
允許tomcat接收“{”這樣的特殊字符,重啟后問題依然沒有解決,又修改nginx配置文件也不行。
接着又查詢到:
根據rfc規范,url中不允許有 |,{,}等特殊字符,但在實際生產中還是有些url有可能攜帶有這些字符,特別是|還是較為常見的。在tomcat升級到7以后,對url字符的檢查都變嚴格了,如果出現這類字符,tomcat將直接返回400狀態碼。
后來有人對此提出了異義,見: https://bz.apache.org/bugzilla/show_bug.cgi?id=60594
經過一番討價還價,tomcat的開發人員增加一項設置,允許配置在url可以出現的特殊字符,但也僅限於|,{,}三種,見:http://tomcat.apache.org/tomcat-8.0-doc/config/systemprops.html#Other
該項設置在以下版本的tomcat中有效:
- 8.5.x for 8.5.12 onwards
- 8.0.x for 8.0.42 onwards
- 7.0.x for 7.0.76 onwards
這個只是允許出現一些特殊字符,並沒有說是全部特殊字符。
后來終於發現是tomcat的版本問題,好像是tomcat7.9以上的版本,都不支持請求鏈接上帶有特殊字符.否則會報400錯誤,
tomcat請求中包含特殊字符 [] | {} 發送get請求失敗:
原因:
400錯誤的解決方式:
方法一 : 降低tomcat的版本
方法二: 修改server.xml
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" relaxedQueryChars="[]|{}^\`"<>" redirectPort="8443" />
方法三: 修改server.xml
在Host里加入:<Valve className="org.apache.catalina.valves.ErrorReportValve" showReport="false" showServerInfo="false" />
方法三修改后只會顯示出HTTP 400 錯誤,不會打印堆棧和tomcat版本號信息
關於方法三的解釋:
HTTP狀態代碼提供有關請求的HTTP請求成功完成的信息。HTTP響應分為五個類,如下所示:
- 信息回應
- 成功的回應
- 重新導向
- 客戶錯誤
- 服務器錯誤
在這里,我們的目的是使用HTTP響應代碼處理HTTP請求時生成的錯誤/異常。您可以從HTTP狀態代碼信息中找到有關HTTP狀態代碼的更多詳細信息。
該錯誤報告閥是一個錯誤處理程序,其處理錯誤狀態代碼與錯誤狀態碼或異常和服務器信息的信息錯誤頁上相應地重定向用戶。
該錯誤報告閥用於與Tomcat服務器編寫自定義的錯誤報告處理功能。
在這里,我們將在Catalina(Tomcat)中創建自定義錯誤報告閥。錯誤報告閥用於報告錯誤/異常。因此,如果發生任何錯誤(例如404,400等),它將處理該錯誤並為我們提供默認的tomcat頁面,如下所示(400錯誤請求的示例)。
在此上方,它將為您提供狀態報告信息(HTTP狀態)和服務器信息。因此,您可以在Tomcat服務器的conf 中使用server.xml對其進行配置。
默認的Catalina錯誤報告閥門和配置:org.apache.catalina.valves.ErrorReportValve
屬性 | 描述 |
showReport | 如果發生錯誤,用於在錯誤頁面上顯示錯誤信息(狀態代碼及其信息)的標志。默認值是true |
showServerInfo | 如果發生任何錯誤,則用於在錯誤頁面上顯示當前服務器信息的標志。默認值是true |
現在,添加/更新以下內容以在<Host> 中的server.xml中進行配置。
<Valve className="org.apache.catalina.valves.ErrorReportValve" showReport="false" showServerInfo="false" />
現在,使用上述配置,您將發現以下內容。(僅HTTP狀態代碼)。
注意:同時禁用showServerInfo和showReport只會返回HTTP狀態代碼,並從默認響應中刪除所有CSS。
參考地址:https://aspiresoftware.in/blog/catalinatomcat-custom-error-report-valve-to-handle-errors-exceptions/