在将华丹快速开发平台以nginx+tomcat方式布署时,并在nginx中配置成https方式访问。发现有些模块打开后是空白页,通过浏览器F12查看控制台发现如下类似错误:
Mixed Content: The page at 'https://www.huadaninfo.com/charisma/index.jsp' was loaded over HTTPS, but requested an insecure resource 'http://www.huadaninfo.com/charisma/system.report.do?subSys=system&repID=95&isQuery=1'. This request has been blocked; the content must be served over HTTPS.
如错误提示:就是在https访问环境中,出现了http访问,为了安全,浏览器禁止这种混合访问。
这里需要明确一点,配置https访问时,除了nginx,tomcat也需要配置https吗? 正常来说是不需要的,因为外网访问的都是通过https访问nginx,对于动态内容是在本机或局域网内反射给tomcat的,所以完全可以通过http方式访问。
形如:
upstream website {
server 127.0.0.1:8089;
}
location ~* \.(jsp|do|action)$
{
# 真实的客户端IP
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
# 请求头中Host信息
proxy_set_header Host $host; #:$server_port;
# 代理路由信息,此处取IP有安全隐患
#String ip=request.getHeader("X-Forwarded-For");java中取远程IP需要该项,否则返回nginx地址127.0.0.1
proxy_set_header X-Forwarded-For $remote_addr;#$proxy_add_x_forwarded_for;
# 真实的用户访问协议
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://website;
expires -1;
}
并且在nginx中通过如下配置,将http重定向成https:
server{
listen 80;
server_name huadaninfo.com www.huadaninfo.com;
location / {
rewrite ^/(.*)$ https://www.huadaninfo.com/$1 permanent;
}
}
同时,在华丹快速开发平台中,所有的程序(包括java,js,css)中都通过相对目录访问的,不是绝对目录访问的,因此在https访问环境中,不会出现http的访问方式才对。
最后通过试验发现:在nginx配成https,通过http方式反向到tomcat时,在web应用程序中,如果是通过response.sendRedirect(urlPath),重定向的页面,此时就是通过http的方式访问。
这种情况无法避免,tomcat版本用的是9.0,不知是否可以通过tomcat配置避免这种情况。
网上主要是通过upgrade-insecure-requests 这个CSP指令解决,可以让浏览器帮忙做这个转换。启用这个策略后,有两个变化:
页面所有 HTTP 资源,会被替换为 HTTPS 地址再发起请求;页面所有站内链接,点击后会被替换为 HTTPS 地址再跳转。
主要有两种方式:
1、在所有页面的head中加入,<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">,华丹快速开发平台可以通过include\htmlHeader.jsp一次性修改,但这种方式有局限性,一是在非https中会影响显示,主要是js,css访问出错,二是很多url并不是页面,形如system.report.do,这种情况如果在程序中硬编码写入Content-Security-Policy,也不方便。
2、在nginx.cnf中的server段加上:
add_header Content-Security-Policy upgrade-insecure-requests;
这个方法比较简单,也有效,但注意是要在server段中加,不能只在location ~* \.(jsp|do|action)$ 段加,否则有些资源无效。这种是否需要重定向了一次,影响效率,还有待研究。
除上述方式外,经实验,还可以在nginx.cnf主server中加入proxy_redirect http:// https://;专门解决由response.sendRedirect()引发的将https转成http的问题。这个方法比add_header Content-Security-Policy upgrade-insecure-requests;更适合。
其实还可以将tomcat也配成https方式(ssl),这样更安全,而且保证效率,tomcat的https设置好后,在nginx.cnf中如下配置:
upstream website {
server 127.0.0.1:1443;
}
location ~* \.(jsp|do|action)${
...
proxy_pass https://website;
}