[英]Why does my Java servlet filter not work over HTTPS?
Spring(Boot)在這里,雖然這根本不重要。 我正在嘗試了解有關HTTP / S代理如何工作的更多信息以及構建一個在我的機器上本地運行的代理。 我編寫(並注冊)了一個servlet過濾器,用一個愚蠢的HTML消息替換HTTP響應的主體:
public class DummyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletResponse httpServletResponse = (HttpServletResponse)response;
String html = "<html><head><title>Awesome!</title></head><body>Proxy is working!</body></html>";
httpServletResponse.writer.write(html);
httpServletResponse.writer.flush();
return;
}
@Override
public void destroy() {
}
}
然后我運行我的Spring應用程序,並將瀏覽器的代理設置更改為指向我的應用程序( localhost:8080
)。
我現在能夠訪問HTTP網站,看到我的虛擬消息(“ 代理正在工作! ”)作為HTML輸出。 成功!!! 然而,我然后去了谷歌的主頁,顯然使用HTTPS,谷歌主頁渲染得很好。
所以我改變了我的瀏覽器以使用我的Spring應用程序代理SSL(再次, localhost:8080
)並再次嘗試。 這次我去谷歌時,我的瀏覽器給了我一個錯誤,說明連接有問題。 我認為這是因為我的愚蠢簡單代理導致瀏覽器和需要SSL的網站(在本例中為Google)之間的SSL“握手”問題。
我知道在SSL上使用代理肯定是可能的,因為(至少) Charles Proxy可以配置為執行此操作。 顯然,Charles根據自己的根CA證書動態生成您嘗試訪問的站點的證書。 Charles和SSL站點使用該站點的證書,瀏覽器和Charles之間的通信使用Charles的證書。
但是知道這並沒有幫助我理解為什么我的簡單代理首先在SSL-land中引起問題。 我需要在代碼中進行哪些更改才能使其與HTTPS的行為相同,與HTTP相同?
我想知道以下是否適合我:
*.example.com
創建一個自簽名通配符證書(任何dot com) localhost:443
https://example.com
下的任何URL時,瀏覽器會聯系我的代理,代理服務於自簽名證書(現在它信任),代理可以與example.com
交談網站的實際證書就好了。 這或類似的東西會解決我的問題嗎?
表明的問題確實是HTTP / S基本問題。
當指示您的瀏覽器在給定地址( localhost:8080 )使用代理時,瀏覽器會對配置的“代理服務器”進行任何后續HTTP調用,指示此“代理”它應該代表調用執行調用瀏覽器到原始URL。
在您的情況下,“代理”實際上是返回一個預制消息,並沒有真正嘗試連接到原始URL。 (至少你沒有告訴任何關於你的“代理服務器”將要聯系最初目標站點的事情。)這將是代理基本功能的更重要方面。
在使用HTTPS連接到服務器的情況下,重要的是,您如何配置與瀏覽器的代理連接。
可以使用與代理的純HTTP連接,並仍然請求代理使用HTTPS連接進行“外部”調用。 (然而,這樣的配置並不是那么普遍,因為代理需要仔細處理重定向。此外,它會使首先使用HTTPS的一些收益無效(至少在從瀏覽器到代理的通信段上)。
很可能您的瀏覽器配置使用HTTPS連接到“代理”( localhost:8080 )。 然后,瀏覽器嘗試了HTTPS請求,並在目標“使用常規HTTP”響應時遇到錯誤。
將代理servlet配置為接受HTTPS調用將“修復”該問題。 (從此處,“更新”編輯中的步驟將“解決”錯誤。)但是,您不需要在localhost使用端口443。 任何端口都可以。 如果您想同時提供HTTP和HTTPS代理,您需要分配兩個端口(例如,您可以使用8080用於HTTP,8081用於HTTPS)。
只是為了解釋:看到“代理正在工作”消息並不能證明有一個工作代理。 它只是證明您的瀏覽器確實與您的servlet通信。 (因為您沒有讀取任何標頭信息,所以它與直接調用URL localhost:8080沒有區別。)
除了“聯系”之外,工作代理還需要接收請求,分析傳入的標頭並根據標准做出反應(特別是執行請求的“外部”調用並返回結果)。 (當然,您已經閱讀了與HTTP協議相關的RFC(例如RFC7230)?)
您必須創建HTTPS連接器。 要創建HTTPS連接器,您需要做一些事情; 但最重要的是,您需要生成證書密鑰庫,用於加密和解密與瀏覽器的SSL通信。
如果您使用的是Unix或Mac,則可以通過運行以下命令來執行此操作: $ JAVA_HOME / bin / keytool -genkey -alias tomcat -keyalg RSA在Windows上,可以通過以下代碼實現: “%JAVA_HOME%\\ bin \\ keytool“-genkey -alias tomcat -keyalg RSA
在創建密鑰庫期間,您應輸入適合您的信息,包括密碼,名稱等。 出於執行完成的目的,新生成的密鑰庫文件將出現在主目錄中,名稱為:.keystore。 注意您可以在tomcat中找到有關准備證書密鑰庫的更多信息。
完成密鑰庫創建后,您需要創建單獨的屬性文件,以便存儲HTTPS連接器的配置,例如端口和其他。 之后,您將創建一個配置屬性綁定對象,並使用它來配置我們的新連接器。
請參閱prop文件的此示例。 你可以用你想要的任何名字命名:tomcat.https.properties
custom.tomcat.https.port=8443
custom.tomcat.https.secure=true
custom.tomcat.https.scheme=https
custom.tomcat.https.ssl=true
custom.tomcat.https.keystore=${user.home}/.keystore
custom.tomcat.https.keystore-password=changeit
不需要更改您的代碼。您可能缺少配置。檢查您是否正確配置了ssl。 按照以下步驟在spring應用程序中啟用ssl:
創建密鑰庫文件
keytool -genkey -alias tomcat -keyalg RSA
2.配置Tomcat以使用密鑰庫文件 - server.xml中的SSL配置
找到以下聲明:
<!--
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" />
-->
取消注釋並將其修改為如下所示:
Connector SSLEnabled="true" acceptCount="100" clientAuth="false"
disableUploadTimeout="true" enableLookups="false" maxThreads="25"
port="8443" keystoreFile="/Users/prashant/.keystore" keystorePass="password"
protocol="org.apache.coyote.http11.Http11NioProtocol" scheme="https"
secure="true" sslProtocol="TLS" />
3.配置您的應用程序以使用SSL(通過https:// localhost:8443 / yourApp訪問 )
添加應用程序的web.xml文件。
<security-constraint>
<web-resource-collection>
<web-resource-name>securedapp</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
它適用於我的自定義過濾器。
希望所以它會幫助你..
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.