Nginx背后的Tomcat:如何在非标准端口上同时代理HTTP和HTTPS? 描述
我们正在为不同的客户端安装一些在Nginx后面运行tomcat6的应用程序。其中有些安装仅限于HTTP,有些仅限于HTTPS,有些地方两者兼而有之。由于缺少公共IP,其中一个安装在非标准端口(8070和8071)上使用HTTP和HTTPS。手边的应用程序在另一个应用程序中显示为iframe 当前行为 Tomcat将所有HTTPS请求重定向到HTTP(因此,由于浏览器对混合内容的限制,iframe中不会显示任何内容) 当前配置 Iframe代码: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: <
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;
}
期望的行为
标记,那么配置Nginx将困难得多listen 8071 ssl spdy;
)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。