我如何知道对 servlet 的请求是使用 HTTP 还是 HTTPS 执行的?

Posted

技术标签:

【中文标题】我如何知道对 servlet 的请求是使用 HTTP 还是 HTTPS 执行的?【英文标题】:How can I know if the request to the servlet was executed using HTTP or HTTPS? 【发布时间】:2012-01-02 07:19:18 【问题描述】:

我用 Java 编写了一个 servlet,我想知道对该 servlet 的请求是使用 HTTP 还是 HTTPS 执行的。

我以为我可以使用 request.getProtocol(),但它在两种方法上都返回 HTTP/1.1。

有什么想法吗?

【问题讨论】:

【参考方案1】:

HttpSerlvetRequest.isSecure() 就是答案。 ServletContainer 负责在以下情况下返回 true:

如果 ServletContainer 本身可以接受 https 上的请求。 如果ServletContainer前面有LoadBalancer。并且,LoadBlancer 在 https 上得到了请求,并在 plain http 上将请求发送到了 ServletContainer。在这种情况下,LoadBalancer 向 ServletContainer 发送 X-SSL-Secure : true 标头,这应该得到遵守。

当在 https 上收到请求时,容器还应使此请求属性可用:

javax.servlet.http.sslsessionid javax.servlet.request.key_size javax.servlet.request.X509Certificate

【讨论】:

你能分享一下你从哪里得到'X-SSL-Secure:true'位吗?我一直在搜索,但找不到有关此标题的更多信息。 这不适用于我的环境:Apache 2.4.10 作为前端代理;在 java 中似乎不可能知道请求是使用 http 还是 https 到 apache 完成的。当然,我将它作为 http 到 Java 获取,但我需要知道前端代理是如何被访问的。 - 事实上,正如@Zotov 也提到的:几乎没有关于 X-SSL-Sercure 标头的信息。所以我认为这没有得到广泛实施?! 标头名称可能会有所不同,因为它不是很标准。但是,这里的概念是代理可以添加有关 SSL 的标头,并且服务器可以读取它们。对于 Ex,nginx 添加了 X-SSL-Protocol。它也可以用自定义标题替换。 我猜,您使用任何特定的负载均衡器作为 f5 并且“X-SSL-Secure : true”是一个可选标头,它不是任何(甚至不是负载均衡器)标准的一部分,对吧?【参考方案2】:

您不能可靠地依赖端口号。 但是您可以依赖该方案:

使用:request.getScheme() 查看是否为https

如果是,那么它是安全连接。

我相信无论 Tomcat 版本如何,这都应该可以工作

【讨论】:

isSecure 至少可以追溯到 1.2,并且不是 Tomcat 特定的。【参考方案3】:

isSecure。请务必检查继承的方法。

【讨论】:

【参考方案4】:

https 和 http 在不同的端口上运行。所以你可以从请求中获取端口,知道请求来自哪个端口,这样你就可以知道协议。 int port=request.getServerPort();

【讨论】:

@Krishnan 端口号是任意的...我可以在 443 上运行 HTTP,在 80 上运行 HTTPS 或它们的任意组合。

以上是关于我如何知道对 servlet 的请求是使用 HTTP 还是 HTTPS 执行的?的主要内容,如果未能解决你的问题,请参考以下文章

当发送的请求是 Ajax 请求时,如何从 ManagedBean 重定向?

servlet工作原理

如何知道请求是使用 HTTP 1.x 还是 HTTP2 执行的

关于DeferredResult的思考

Linux中的请求是如何通过nginx转发到tomcat

关键依赖:依赖的请求是一个表达式,当使用 v-bind 时