我如何知道对 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 执行的?的主要内容,如果未能解决你的问题,请参考以下文章