Nginx背后的Tomcat:如何在非标准端口上同时代理HTTP和HTTPS? 描述

Nginx背后的Tomcat:如何在非标准端口上同时代理HTTP和HTTPS? 描述,tomcat,nginx,reverse-proxy,Tomcat,Nginx,Reverse Proxy,我们正在为不同的客户端安装一些在Nginx后面运行tomcat6的应用程序。其中有些安装仅限于HTTP,有些仅限于HTTPS,有些地方两者兼而有之。由于缺少公共IP,其中一个安装在非标准端口(8070和8071)上使用HTTP和HTTPS。手边的应用程序在另一个应用程序中显示为iframe 当前行为 Tomcat将所有HTTPS请求重定向到HTTP(因此,由于浏览器对混合内容的限制,iframe中不会显示任何内容) 当前配置 Iframe代码: Tomcat的server.xml: <

我们正在为不同的客户端安装一些在Nginx后面运行tomcat6的应用程序。其中有些安装仅限于HTTP,有些仅限于HTTPS,有些地方两者兼而有之。由于缺少公共IP,其中一个安装在非标准端口(8070和8071)上使用HTTP和HTTPS。手边的应用程序在另一个应用程序中显示为iframe

当前行为 Tomcat将所有HTTPS请求重定向到HTTP(因此,由于浏览器对混合内容的限制,iframe中不会显示任何内容)

当前配置 Iframe代码:


Tomcat的
server.xml

<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           proxyPort="80"
/>

<Connector port="8443" protocol="HTTP/1.1"
           connectionTimeout="20000"
           proxyPort="443"
           scheme="https" secure="true"
/>

Nginx vhost:

server {
  listen 80;
  listen 443 ssl spdy;

  location /saiku-ui {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass http://saiku-server; # This is upstream name
    proxy_redirect off;
  }
}

upstream saiku-server {
  server ip.of.tomcat.server:8080;
}
期望的行为
  • Tomcat应该在一个端口上侦听HTTP和HTTPS请求

    如果将有两个
    标记,那么配置Nginx将困难得多

  • Tomcat不应该在模式之间重定向

  • Nginx可以在任意端口上侦听(例如,
    listen 8071 ssl spdy;
  • Tomcat生成的链接应该是相对的,或者包括Nginx提供的模式、主机和端口
  • 附加信息 我尝试将
    schema
    proxyPort
    属性添加到
    ,之后Tomcat将始终从HTTP重定向到HTTPS(至少更好)


    我不能用谷歌搜索这样的配置,也没有使用Tomcat的经验。请帮助。

    事实上,我想要的确实是不可能的,因此需要在Nginx中有两个独立的
    连接器
    标记和两个上游,如下所示:

    Tomcat的
    server.xml

    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               proxyPort="80"
    />
    
    <Connector port="8443" protocol="HTTP/1.1"
               connectionTimeout="20000"
               proxyPort="443"
               scheme="https" secure="true"
    />
    
    请注意,Tomcat在8080和8443端口上都接收普通HTTP通信(没有SSL,由Nginx终止),但对于8443端口上的连接,它将生成链接,必须以https://开头,而不是HTTP://(通过属性
    scheme=“https”secure=“true”
    ),并将链接插入端口中,在
    proxyPort
    属性中指定


    Nginx将终止SSL并通过上游
    saiku服务器https
    代理所有到Tomcat的8443端口的安全连接,其中
    https
    $scheme
    Nginx请求变量的值(请参见
    location
    block)

    <,还有另一个基于的解决方案

    在谷歌上呆了几个小时后,我发现没有像官方支持的配置那样的标准解决方案,请参阅

    请参阅java文档

    使用指定的重定向位置URL向客户端发送临时重定向响应。此方法可以接受相对URLservlet容器必须将相对URL转换为绝对URL,然后才能将响应发送到客户端。如果位置是相对的,没有前导“/”,则容器将其解释为相对于当前请求URI。如果位置与前导“/”相对,则容器将其解释为相对于servlet容器根

    HttpServletResponseWrapper

    import org.apache.commons.lang.StringUtils;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpServletResponseWrapper;
    import java.io.IOException;
    
    public class SendRedirectOverloadedResponseBasedOnXForwardedProtocol extends HttpServletResponseWrapper {
    
        private HttpServletRequest request;
    
        public SendRedirectOverloadedResponseBasedOnXForwardedProtocol(HttpServletRequest request,
                                                                       HttpServletResponse response) {
            super(response);
            this.request = request;
        }
    
        public void sendRedirect(String location) throws IOException {
    
            String xForwardedProtocol = request.getHeader("X-Forwarded-Protocol");
            String host = request.getHeader("Host");
            if (StringUtils.isNotBlank(xForwardedProtocol) && StringUtils.isNotBlank(host) && !isUrlAbsolute(location)) {
                location = xForwardedProtocol + "://" + host + location;
            }
            super.sendRedirect(location);
        }
    
        public boolean isUrlAbsolute(String location) {
            location = location == null ? "" : location;
            return location.toLowerCase().startsWith("http");
        }
    }
    
    滤器

    import javax.servlet.*;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    
    public class SendRedirectBasedOnXForwardedProtocolFilter implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            chain.doFilter(request, new SendRedirectOverloadedResponseBasedOnXForwardedProtocol((HttpServletRequest) request, (HttpServletResponse) response));
        }
    
        @Override
        public void destroy() {
        }
    }
    

    尝试:我想这就是你正在“尝试”做的。我已经读过这篇文章了。这是仅用于HTTPS设置的配置,但我需要HTTP和HTTPS。无论如何,谢谢您的帮助。您不能在同一端口中使用http和https。