重定向不使用Https

时间:2016-08-25 23:13:11

标签: java redirect servlets load-balancing

我有一个位于硬件负载平衡器后面的Java servlet。负载均衡器仅允许https请求。问题是,当我在servlet中获取请求时,我只能看到http,它似乎已经在到达servlet时被解密,这是有道理的,因为servlet不应该担心安全性。但是,当我想在servlet中发送重定向时,请求将被负载均衡器阻止,因为它将是一个http请求。

我读到了一些解决方案,它们都与this one类似。基本上人们建议首先添加一个servlet过滤器来捕获请求URL。

我试过但它没有用。我不太明白的是,只要servlet无法知道实际请求(http / https),servlet过滤器如何做任何帮助?我也想知道这个问题是否有任何标准解决方案,因为我认为这很常见。

3 个答案:

答案 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");
}