nginx 反向代理重定向到 http 而不是 https

问题描述:

具有以下设置:NGINX(端口 443)>码头 (9090 端口) >弹簧控制器

Having the following setup: NGINX (Port 443) > Jetty (Port 9090) > Spring Controller

为了简化问题,我使用了以下文件:

For simplifying the problem I use the following files:

  • /main.html 包含调用 spring 控制器的 iframe /test
  • spring controller /testreturn "redirect:/iframe.html";
  • /iframe.html 带有简单的文字这是 IFrame"

使用 HTTP 没有问题,但在将 NGINX 配置切换到 HTTPS 后,我在浏览器中收到以下错误并且未显示 iframe:

With HTTP there is no problem but after switching the NGINX configuration to HTTPS I get the following error in the browser and the iframe is not displayed:

main.html:7 混合内容:https://dev/main.html"页面已通过 HTTPS 加载,但请求了不安全的帧'http://dev/iframe.html'.此请求已被阻止;这内容必须通过 HTTPS 提供.

main.html:7 Mixed Content: The page at 'https://dev/main.html' was loaded over HTTPS, but requested an insecure frame 'http://dev/iframe.html'. This request has been blocked; the content must be served over HTTPS.

所以控制器重定向到 http 而不是 https,这是我的 NGINX 配置,根据我的理解,它应该让码头/控制器知道它正在 https 上运行:

So the controller redirects to http instead of https, this is my NGINX configuration which from my understanding should let the jetty/controller know that it is running on https:

 server {
    listen 443      ssl http2;
    listen [::]:443 ssl http2;
    server_name dev;

    ssl on;
    ssl_certificate ...;
    ssl_certificate_key ...;

    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Port $server_port;
        
        proxy_ssl_name $host;
        proxy_ssl_server_name on;

        proxy_pass http://127.0.0.1:9090;
    }
}

你需要做的几件事...

You need to do a few things ...

  1. 在 nginx 方面,使用来自 RFC7239 的标准 Forwarded 标头,而不是 X-Forwarded-* 标头.这是因为 X-Forwarded-* 标头不是标准,并且在它们的用法上存在冲突.(在您的示例中,您将端口分开,这现在也与端口的host"、proto"和for"用法冲突)

  1. On the nginx side, Use the Standard Forwarded header from RFC7239, not the X-Forwarded-* headers. This is because the X-Forwarded-* headers are not a standard and conflict in meaning across their usage. (in your example, you made the port separate, which now conflicts with the "host", "proto", and "for" usages for the port as well)

在 Jetty 端,启用 ForwardedRequestCustomizer.这将查找各种转发标头并更新请求的权限、原型和安全".适当地标记.

On the Jetty side, enable the ForwardedRequestCustomizer. This will look for the various Forwarding headers and update the request's authority, protos, and "is secure" flags appropriately.

在 Jetty 端,将 HttpConfiguration.securePort 配置为 nginx 上 SSL/TLS 的端口,而不是 Jetty 本身使用的端口.

On the Jetty side, configure the HttpConfiguration.securePort to be the port for your SSL/TLS on your nginx, not the port that Jetty itself uses.