我有一个位于硬件负载平衡器后面的Java servlet。负载均衡器仅允许https请求。问题是,当我在servlet中获取请求时,我只能看到http,它似乎已经在到达servlet时被解密,这是有道理的,因为servlet不应该担心安全性。但是,当我想在servlet中发送重定向时,请求将被负载均衡器阻止,因为它将是一个http请求。
我读到了一些解决方案,它们都与this one类似。基本上人们建议首先添加一个servlet过滤器来捕获请求URL。
我试过但它没有用。我不太明白的是,只要servlet无法知道实际请求(http / https),servlet过滤器如何做任何帮助?我也想知道这个问题是否有任何标准解决方案,因为我认为这很常见。
答案 0 :(得分:1)
您实际上可以知道负载均衡器的请求是http还是https。负载均衡器会向您发送某些标题,告诉您原始请求。
对于Ex,如果加载均衡器的请求是HTTPS,它将发送 X-SSL-Secure:true 标头。
请参考这里。
How can I know if the request to the servlet was executed using HTTP or HTTPS?
答案 1 :(得分:0)
HTTPS只是基于SSL的HTTP协议。它只加密客户端和客户端之间传输的数据包。服务器使用证书。
您的Servlet不应该打扰使用什么底层机制。传输协议是您的客户与客户之间的合同。容器。您的servlet对于在网络级别进行通信的方式保持透明。
您获得的重定向警告可能是因为安全强制执行。通常,大多数现代浏览器允许您从HTTP转到HTTPS而不是其他方式。
例如 - 如果您的主页是以HTTPS加载的,但您的浏览器将阻止您通过HTTP进行的异步调用(任何ajax调用)。这样做是为了强制您在站点上的所有页面上使用HTTPS。
此处可能有两种情况需要检查:
1)您是否在客户端浏览器中收到此警告。正如我上面已经解释的那样,这可能是导致问题的原因。
2)与浏览器一样,您的负载均衡器可能会执行任何此类安全措施。
提示:通常每当我们在servlet或任何后端代码中使用重定向时。不管在哪里使用URL,都不要明确指定协议。它可能在您的重定向代码或任何其他地方。即使在你正在生成的锚标签中
不要写:
<a href="http://mywebsite.com/page1"> page1 </a>
相反,让您的客户端浏览器处理协议(此外,如果URL位于同一个域中,还使用域相对URL。仅当它们位于您的站点外部时才使用绝对URL。)
<a href="mywebsite.com/page1"> page1 </a>
这样,无论您是否使用HTTPS,都可以使用相同的servlet /后端代码。
还有一件事:SSL或HTTP over SSL位于您的客户端和客户端之间。网络服务器层。您的容器/应用服务器不会(或不应该)知道它们之间发生了什么。还建议您在网络服务器和网络服务器之间使用SSL。 Appserver并具有端到端加密功能。
答案 2 :(得分:0)
在执行以下行之前,我们需要在适当的条件下重定向请求。
response.sendRedirect("some.jsp");
保持如下所示的架构/引用:
String scheme = request.getScheme();
String referer = request.getHeader("referer");
最好使用引荐来源网址,因为架构并不总是能够提供所需的结果。您可以在控制台调试器中检查该值。
然后在这样的条件下执行重定向:
String servername = request.getServerName();
String scheme = request.getScheme();
String referer = request.getHeader("referer");
if(referer.startsWith("https")) {
response.sendRedirect("https://" + servername + "/context-root/" + "some.jsp");
}else{
response.sendRedirect("some.jsp");
}