Rah*_*hul 4 ssl tomcat nginx amazon-web-services amazon-elb
我在 AWS 上有以下设置
ELB(终止SSL)-> nginx 在80 上接收http 并转发到-> 8080 上的tomcat
但是当我在我的 servlet 中执行 response.sendRedirect("/somepath") 时,浏览器将它作为 302 http://example.com/somepath接收
但我希望浏览器获得https://example.com/somepath,我如何在 tomcat 或 nginx 中实现这一点而不在它们上设置 SSL。
这是因为 response.sendRedirect();
SSL 卸载服务器实际上会导致 https URL 在 sendRedirect 的情况下转换为 http URL 的问题。让我们试着了解这一切是如何发生的。当 https URL 到达中间 SSL 卸载服务器时,请求被解码(以卸载原本由实际目标服务器完成的解码任务)为 http 请求,并且 SSL 卸载器现在将解码后的 http 请求发送到实际目标服务器(它也可能为了其他目的而通过一些其他中间服务器)。现在,目标服务器不知道它最初是否是 https 请求,它仅将其视为 http 请求。这就是为什么在目标服务器上调用 sendRedirect 的 servlet 将导致重定向资源的 http URL(具有相对 URL)并将相同的 http URL 发送回客户端浏览器的原因。请记住,此 URL 不会出现 SSL 卸载服务器,因为它是 http 请求而不是 https 请求。如果重定向的资源是绝对 https URL,那么中间 SSL 卸载器也可以在该 https 请求到达客户端浏览器之前将该 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));
}
}
Run Code Online (Sandbox Code Playgroud)
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);
}
}
Run Code Online (Sandbox Code Playgroud)
资源来自这里:
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