繁体   English   中英

为什么我的Java servlet过滤器不能通过HTTPS工作?

[英]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相同?


更新

我想知道以下是否适合我:

  1. *.example.com创建一个自签名通配符证书(任何dot com)
  2. 配置我的Sring应用程序以使用此wildcart证书并从端口443提供HTTPS(HTTPS默认值)
  3. 将浏览器的SSL代理设置配置为指向localhost:443
  4. 将我的自签名通配符证书添加到浏览器的信任存储区
  5. 现在,当我访问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:

  1. 创建密钥库文件

    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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM