我如何知道对 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 重定向?