在 Tomcat 中将 HTTP 重定向到 HTTPS:PORT

Posted

技术标签:

【中文标题】在 Tomcat 中将 HTTP 重定向到 HTTPS:PORT【英文标题】:Redirect HTTP to HTTPS:PORT in Tomcat 【发布时间】:2016-01-17 11:14:27 【问题描述】:

我有一个正在运行的 tomcat 应用程序,它已经具有以下从 HTTP 到 HTTPs 的重定向规则:

<Connector executor="tomcatThreadPool"
               port="80" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="443" />

是否可以添加一个例外/规则,即特定 HTTP 请求 (http://www.example.com) 将被重定向到另一个特定地址,指定端口(例如 https://www.example.com:8443/test),而不更改/删除上述连接器?

【问题讨论】:

互联网似乎无法就这个问题的单一、完整和有效的解决方案达成一致。希望你能得到一些帮助here in my post。最后,我不得不费尽心思才想出这个。 @ADTC 您的帖子是关于 AWS Elastic Beanstalk,这个问题是关于 Apache Tomcat。我很困惑为什么你认为这两者是相关的? @Frans 公平点。 EB 服务器正在运行 Apache Tomcat。是的,它特别适用于 AWS EB,但它仍然与 Tomcat 相关。即使在其他云服务或 Tomcat 安装中,有人可能会发现它很有用,可以作为他们寻找解决方案的提示。 ????‍♂️如果你觉得没有帮助,那么忽略它???? (另外,这差不多是 4 年前的事了。我已经开始尝试新事物了。) 【参考方案1】:

您显示的连接器配置不会以您想象的方式重定向特定 URL。

如果您为该 servlet 容器内的 Web 应用程序配置了 CONFIDENTIAL 传输保证,则该配置会起作用。

我的意思是,如果您在该连接器上部署了任何应用程序,其web.xml 描述符具有security-constraint,如下所示:

<security-constraint>

    <web-resource-collection>
        <web-resource-name>Secured</web-resource-name>
        <url-pattern>/*</url-pattern>
    </web-resource-collection>

    ...

    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>

</security-constraint>

然后,Tomcat 会将任何匹配的url-pattern 重定向到配置的端口,以便使用 HTTPS 作为传输机密性的保证。

所以,如果你想重定向一个特定的 URL,你必须用特定的应用程序配置来补充连接器的配置。

编辑

正如您在评论中所建议的,这可能是使此配置正常工作的另一个步骤。如图所示配置 http 连接器,然后按照我告诉您的配置应用程序后,您只需确保您的 Tomcat 服务器配置了 HTTPS 连接器,其他方式重定向将不起作用。

要配置此 HTTPS 连接器,您可以使用如下配置:

<Connector connectionTimeout="20000"
    acceptCount="100" scheme="https" secure="true"
    port="443" clientAuth="false" sslProtocol="TLS"  
    keystoreFile="PATH_TO_KEY_STORE"  
    keystorePass="KEY_STORE_PASS"  
    keyAlias="KEY_STORE_ALIAS"/>  

这是一个示例配置,我没有将一些对您很重要的属性作为线程属性、执行程序等。

最重要的是提供 HTTPS 连接所需的 KeyStore 配置。 Here你有官方文档为Tomcat准备一个java KeyStore来服务HTTPS。

【讨论】:

感谢您的回复,我仍然缺少一些东西 - 我必须进行哪些更改/添加,以便按照问题中的说明进行重定向? (包括港口)。如果我希望 example.com/myApp (http) 重定向到 example.com:8443/mysecondapp (https) - 我应该进行哪些 contexts\connectors\web.xml 更改?【参考方案2】:

您可以通过将其添加到 tomcat_dir/conf/web.xml 的末尾来对部署到 tomcat 的每个应用程序执行此操作:

<security-constraint>
    <web-resource-collection>
        <web-resource-name>Entire Application</web-resource-name>
        <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <!-- auth-constraint goes here if you requre authentication -->
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>

因此您不必在 webapp 的 web.xml 上更改它。

应该可以,假设您已经在另一个端口(通常是 443)中使用了 https。如果不这样做,请确保您的 tomcat_dir/conf/server.xml 看起来像这样:

<!-- Default tomcat connector, changed the redirectPortport from 8443 to 443 -->
<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="443" />

<!-- To make https work on port 443 -->
<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
        maxThreads="150" SSLEnabled="true">
    <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol"/>
    <SSLHostConfig>
        <Certificate certificateKeyFile="/your/own/privkey.pem"
            certificateFile="/eyour/own/cert.pem"
            certificateChainFile="/your/own/chain.pem"
            type="RSA" />
    </SSLHostConfig>
</Connector>

【讨论】:

我强烈建议不要在conf/web.xml 中添加&lt;security-contraint&gt;s。 combining constraints 的规则将对任何已经具有&lt;security-contraint&gt; 和 URL 模式 /* 的应用程序产生相反的影响:有效约束将是 union,而不是 intersection.【参考方案3】:

我有一个正在运行的 tomcat 应用程序,它已经具有以下从 HTTP 到 HTTPs 的重定向规则:

正如 malaguna 回答的那样,Connector 配置不是重定向规则。它只是在执行&lt;transport-guarantee&gt;CONFIDENTIAL&lt;/transport-guarantee&gt;触发的重定向时使用的设置。

无法在每个应用程序的基础上覆盖该设置。

如果您需要更好地控制此类重定向,您需要实现自己的过滤器来实现重定向 (if (!request.isSecure()) response.sendRedirect(...);),或配置 3rd party one。

// 从技术上讲,在当前的 Tomcat 8 代码中,transport-guarantee 触发的重定向是由org.apache.catalina.realm.RealmBase.hasUserDataPermission(...) 方法执行的。

【讨论】:

【参考方案4】:

如果你使用tomcat和httpd,你可以使用RewriteEngine

在http.conf中指定端口如下:

NameVirtualHost *:8443 #your specified port
<VirtualHost *:8443>
   ServerName www.example.com
   Redirect permanent / https://secure.example.com/
</VirtualHost>

请参阅:RewriteHTTPToHTTPS 和 Redirect Request to SSL

【讨论】:

【参考方案5】:

将 transport-guarantee CONFIDENTIAL 放在 conf/web.xml 中很好,但它不包括管理器应用程序和主机管理器应用程序(Tomcat 8.5.38)。

我的解决方案是在 conf/context.xml 中放置一个阀门,将所有 http 请求重定向到 https。

https://bitbucket.org/bunkenburg/https-valve/src/master/

【讨论】:

【参考方案6】:

现在回答太晚了,我仍然在分享我的经验,做以下更改

Apache Software Foundation\Tomcat 8.5\conf\web.xml

重新启动。

Pre-Req:配置 https 端口并禁用 http 端口(可选[我做到了])

【讨论】:

在 Mateus 的回答中查看 my comment:这可能与您对某些应用程序的要求相反。例如。如果应用程序需要在所有页面 (/*) 上使用 admin 角色进行身份验证,您的解决方案将允许任何人通过 HTTP 连接到应用程序而无需身份验证。 嗨@PiotrP.Karwasz 把它当作错误答案是错误的,因为我已经在我的服务器上禁用了 HTTP 端口。 我对您答案的当前版本投了反对票,因为:1. 它提供了安全风险(具体示例:将/* 替换为/html/*,您无需身份验证即可连接到Tomcat Manager),2。 Mateus 已经给出了您的解决方案。另请注意,最好将代码/配置添加为文本而不是图像。【参考方案7】:
        <Connector connectionTimeout="20000" port="8081" protocol="HTTP/1.1" redirectPort="443"/>

        <Connector port="443" 
               SSLEnabled="true" 
               acceptCount="100" 
               disableUploadTimeout="true" 
               enableLookups="false" 
               maxHttpHeaderSize="8192" 
               maxThreads="550" 
               minSpareThreads="25"  
               scheme="https" 
               secure="true" 
               compression="on"
               protocol="org.apache.coyote.http11.Http11NioProtocol" 
               sslImplementationName="org.apache.tomcat.util.net.openssl.OpenSSLImplementation">
                   <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol"/> 
                   <SSLHostConfig protocols="TLSv1.2" 
                                  certificateVerification="none" 
                                  ciphers="TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA">
                                        <Certificate type="RSA" 
                                                     certificateKeystoreFile="/ssl/self-signed/your-keystore.jks" 
                                                     certificateKeystorePassword="123456" 
                                                     certificateKeyAlias="your-alias" /> 
                    </SSLHostConfig>
        </Connector>

【讨论】:

以上是关于在 Tomcat 中将 HTTP 重定向到 HTTPS:PORT的主要内容,如果未能解决你的问题,请参考以下文章

tomcat访问的重定向问题

在 Undertow 中将 HTTP 重定向到 HTTPS

如何在 Laravel 4 中将一个路由重定向到 HTTPS,将所有其他路由重定向到 HTTP?

在 Codeigniter 中将 http 重定向到 https

在codeigniter中将站点url http重定向到https

在 apache red hat 中将 http 重定向到 https