我在AWS上进行了以下设置
ELB(终止SSL) - > nginx在80上接收http并转发到 - > tomcat on 8080
但是当我在我的servlet中执行response.sendRedirect(" / somepath")时,浏览器会将其接收为302 http://example.com/somepath
但我希望浏览器获得https://example.com/somepath,如何在tomcat或nginx中实现此功能而不在其上设置SSL。
答案 0 :(得分:4)
这是因为response.sendRedirect();
SSL卸载服务器实际上会导致https网址出现此问题 在sendRedirect的情况下转换为http URL。让我们试试吧 了解这一切是如何发生的。当https URL到达时 中间SSL卸载服务器,请求被解码(卸载 解码任务本来是由实际目标完成的 服务器否则)进入http请求,SSL卸载器现在发送 将http请求解码到实际的目标服务器(它可能会去 通过其他几个中介服务器用于其他目的)。 现在,目标服务器不知道它最初是否为https 请求与否,它仅将其视为http请求。这是 为什么servlet在目标服务器上调用sendRedirect的原因 结果到重定向资源的http URL(有一个亲戚 URL)和相同的http URL被发送回客户端浏览器。 请记住,此URL不会出现SSL卸载服务器 因为它是一个http请求而不是一个https请求。如果重定向 resource是一个绝对的https URL,也是一个中间SSL Offloader之前可以将该https请求转换为http请求 它到达客户端浏览器。
该问题的解决方案是在HttpServletResponseWrapper中实现Filter并覆盖sendRedirect。
过滤
public class AbsoluteSendRedirectFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException { }
public void destroy() { }
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain) throws IOException, ServletException {
//continue the request
chain.doFilter(request, new SendRedirectOverloadedResponse(request, response));
}
}
HttpServletResponseWrapper
public class SendRedirectOverloadedResponse extends HttpServletResponseWrapper {
private HttpServletRequest m_request;
private String prefix = null;
public SendRedirectOverloadedResponse(HttpServletRequest inRequest,
HttpServletResponse response) {
super(response);
m_request = inRequest;
prefix = getPrefix(inRequest);
}
public void sendRedirect(String location) throws IOException {
String finalurl = null;
if (isUrlAbsolute(location)) {
finalurl = location;
} else {
finalurl = fixForScheme(prefix + location);
}
super.sendRedirect(finalurl);
}
public boolean isUrlAbsolute(String url) {
return url.toLowerCase().startsWith("http");
}
public String fixForScheme(String url) {
//alter the url here if you were to change the scheme return url;
}
public String getPrefix(HttpServletRequest request) {
StringBuffer str = request.getRequestURL();
String url = str.toString();
String uri = request.getRequestURI();
int offset = url.indexOf(uri);
String prefix = url.substring(0,offset);
}
}
资源来自这里:
http://www.hoitikwong.com/2013/03/the-mystery-case-of-https-becoming-http.html和
http://geekexplains.blogspot.in/2008/06/https-becoming-http-in-case-of.html
答案 1 :(得分:0)
尝试为LB级别的所有请求设置IS_SSL = ssl请求标头。然后,nginx使用https传递与原始URL一样的响应