如何在ELB后面的tomcat上重定向到https

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。

Ken*_*man 7

这是因为 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