Nginx SSL+tomcat,request.getScheme() 取到的协议不正确

原文地址:https://blog.csdn.net/caicaimaomao/article/details/126362415

现象:使用Nginx代理tomcat,使用https访问,在火狐浏览器下无法访问。

没有使用Nginx时,直接通通过tomcat访问,https://xxxx,系统可以正常访问。但是加上Nginx之后,在谷歌浏览器下可以正常访问,到那时在火狐浏览器访问提示:

Content Security Policy: 升级不安全的请求“http://coach.xxxxx.com/s/js/jquery.js”至使用“https”(未知)
Content Security Policy: 升级不安全的请求“http://coach.xxxxx.com/messageController.do?queryMessageOut”至使用“https”(未知)
Content Security Policy: 升级不安全的请求“http://coach.xxxxx.com/messageController.do?queryMenuOut”至使用“https”

 

 在前后端分离之前,我们一般都是用JSP开发前段页面,这些前端页面和后台程序是放在同一个tomcat 下,在获取项目url时,我们会使用request.getScheme():

<% 
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path;
%>

这样我们就获得了完整的url地址,在引用js时一般会使用如下方式:

<script type="text/javascript" src="<%=basePath %>/js/jquery-1.8.1.min.js"></script>
<script type="text/javascript" src="<%=basePath %>/acharts/acharts.js"></script>

从火狐浏览器控制台打印的结果看,https访问时,这个request.getScheme()获取的协议还是http,查看getScheme源码信息:

Returns the name of the scheme used to make this request, for example, http, https, or ftp. Different schemes have different rules for constructing URLs, as noted in RFC 1738.
Returns:a String containing the name of the scheme used to make this request

这个方法注释写着可以返回http, https, or ftp,并且在没有Nginx的时候是可以正常访问的,说明Nginx转发时并没有带上协议进行转发。HTTP规范中的X-Forwarded-Proto就是用来识别协议的:

X-Forwarded-Proto(XFP)报头是用于识别协议(HTTP 或 HTTPS),其中使用的客户端连接到代理或负载平衡器一个事实上的标准报头。您的服务器访问日志包含在服务器和负载平衡器之间使用的协议,但不包括客户端和负载平衡器之间使用的协议。要确定客户端和负载平衡器之间使用的协议,X-Forwarded-Proto可以使用请求标头。

为了正确地识别实际用户发出的协议是 http 还是 https,需要在Nginx配置文件的location中加入X-Forwarded-Proto:

location / {
    proxy_pass http://gtsserver;
    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;
}

Tomcat的配置文件也要做改动,用来正确的接收转发的协议, 在<Engine name="Catalina" defaultHost="localhost">下面加入:

<Valve className="org.apache.catalina.valves.RemoteIpValve" 
        remoteIpHeader="X-Forwarded-For" 
        protocolHeader="X-Forwarded-Proto" 
        protocolHeaderHttpsValue="https"/>  

 

posted @ 2023-02-23 15:09  kszsa  阅读(201)  评论(0编辑  收藏  举报