问题背景我以如下流程图作为说明

nginx配置如下:

        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $host;

但是在后端的HttpServletRequest的getScheme()方法一直获取到的协议为http,开始以为是nginx中配置的参数没有生效  proxy_set_header X-Forwarded-Proto $scheme; 但是在nginx的access.log中打印看到确实是输出了https, 所以原因只能是后端没有获取到这个参数,经过多方查找资料,原来是在Spring 后端中,HttpServletRequest.getScheme() 默认获取的是当前Servlet容器接收到的请求协议,而不是X-Forwarded-Proto 头的值。 当应用程序部署在反向代理(例如 Nginx)后面时,反向代理通常使用 HTTP 与后端服务通信,即使原始请求是通过 HTTPS 发送的。在这种情况下,request.getScheme() 将会返回 http,因为这是反向代理与后端服务之间实际使用的协议。

HttpServletRequest.getScheme() 方法并不自动识别X-Forwarded-Proto 请求头。为了使后端服务能够识别并利用这个头信息,需要配置Spring服务来信任代理服务器并使用X-Forwarded-* 请求头。

在 application.properties 或 application.yml 中,可以设置下面的属性来启用对X-Forwarded-* 请求头的自动处理:

properties复制代码

server.forward-headers-strategy=framework

或者使用 YAML 格式:

server: forward-headers-strategy: framework

启用了ForwardedHeaderFilter 之后,Spring应用将解析X-Forwarded-Proto、X-Forwarded-Host 和X-Forwarded-Port 请求头,并将这些值用于 HttpServletRequest的getScheme()、HttpServletRequest的getServerPort() 和 HttpServletRequest的getServerName() 等调用。这样,就可以正确地从 HttpServletRequest 获取到使用了https 协议的信息。

我这里是已经可以正确验证了通过HttpServletRequest的getScheme()方法正确获取到了https协议

14:15:27.912 [476697b6a7c56f3b] [http-nio-8080-exec-1] INFO  c.l.a.c.OaFilter - [getFullURL,101] - request.getScheme(): https

更多推荐