如何在ELB后面的tomcat上重定向到https [英] How to redirect to https on tomcat behind ELB

查看:201
本文介绍了如何在ELB后面的tomcat上重定向到https的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在AWS上进行了以下设置

I have following setup on AWS

ELB(终止SSL)-> nginx在80上收到http并在8080上转发到-> tomcat

ELB (terminates SSL) -> nginx receives http on 80 and forwards to -> tomcat on 8080

但是当我在servlet中执行response.sendRedirect("/somepath")时,浏览器将其接收为302 http ://example.com/somepath

But when i do a response.sendRedirect("/somepath") in my servlet then the browser is receiving it as 302 http://example.com/somepath

但是我希望浏览器获取 https://example.com/somepath ,我该如何实现在tomcat或nginx中,而无需在它们上设置SSL.

But I want the browser to get https://example.com/somepath, how do I achieve this in tomcat or nginx without setting up SSL on them.

推荐答案

这是由于response.sendRedirect();

This is because of response.sendRedirect();

SSL卸载服务器实际上导致了https URL的此问题 在sendRedirect的情况下,将其转换为http URL.让我们尝试 了解这一切是如何发生的.当https URL到达 中间SSL卸载服务器,对请求进行解码(以卸载 实际目标会完成的解码任务 服务器))到http请求中,然后SSL Offloader发送 解码到实际目标服务器的http请求(可能会 也可以通过其他一些中间服务器用于其他目的). 现在,目标服务器不知道它最初是否是https 请求与否,并将其仅视为http请求.这是 为什么servlet在目标服务器上调用sendRedirect的原因 结果进入重定向资源的http URL(具有相对 URL)和相同的http URL发送回客户端浏览器. 请记住,此网址不会出现SSL卸载服务器 因为它是一个http请求,而不是一个https请求.如果重定向 资源是一个绝对的https URL,然后也是一个中间SSL 卸载程序可能会在将该https请求转换为http请求之前 它会到达客户端浏览器.

SSL Offloading servers actually cause this problem of https URLs getting converted into http URLs in case of sendRedirect. Let's try to understand how it all happens. When an https URL reaches an intermediate SSL Offloading server, the request is decoded (to offload the decoding task which would have been done by the actual target server otherwise) into an http request and the SSL Offloader now sends that decoded http request to the actual target server (it may go through few other intermediary servers for other purposes as well). Now, the target server has no clue whether it was originally an https request or not and it treats it as an http request only. This is the reason why a servlet calling sendRedirect on the target server will result into an http URL for the redirected resource (having a relative URL)and the same http URL is sent back to the client browser. Remember, no SSL Offloading server will come into picture for this URL as it's an http request and not an https request. If the redirected resource is an absolute https URL then also an intermediate SSL Offloader may convert that https request into an http request before it reaches to the client browser.

该问题的解决方案是在HttpServletResponseWrapper中实现Filter并重写sendRedirect.

The solution to the problem is implementing a Filter and override sendRedirect in HttpServletResponseWrapper.

过滤器.

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

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

Resources came from here:
http://www.hoitikwong.com/2013/03/the-mystery-case-of-https-becoming-http.html and
http://geekexplains.blogspot.in/2008/06/https-becoming-http-in-case-of.html

这篇关于如何在ELB后面的tomcat上重定向到https的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆