标签:set https header server nginx proxy 搬运 com id
oauth2-client在Nginx代理后遇到的问题和解决方案
2020-01-17 2020-05-27
TECH
30 MINUTES READ (ABOUT 4442 WORDS)
OAuth2 Client在实际运用过程中遇到的问题
服务程序集成了OAuth2-Client,以便于用户能够方便集成到支持OAuth2第三方登录的自有业务系统中。开发完成后,本地测试、或者直连服务程序,都没有问题。但凡放到线上环境,经过了nginx 转发后,我们的服务程序OAuth登录永远是以失败告终。
现象如下:
访问需要授权的接口时 https://blog.95id.com:4005/user_attr
,期望是跳转到授权服务器 github.com
进行登录授权,但实际都是跳转到http://blog.95id.com/login`
因为当时直接用服务程序的端口没问题,就将解决思路放在了nginx 转发过程上。
当时线上环境路由规则类似于:
第一层:nginx1 4005 (ssl、负载均配置在这)
第二层:nginx2 4005
第三层:oauth2-client 8082
再看nginx 的配置,第一层nginx 配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
server { listen 4005; server_name blog.95id.com; ssl on; ssl_certificate xxx.crt ...... location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header remote_addr $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://xxxserver_4005; ...... upstream xxxserver_4005 { server {nginx2-ip}:4005; }
|
第二层nginx 的配置如下:
1 2 3 4 5 6 7 8 9 10 11 12
|
server { listen 4005; server_name 0.0.0.0; port_in_redirect off; location / { add_header Cache-Control no-store; proxy_pass http://127.0.0.1:8082; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
|
因为当时nginx配置比较复杂,怎么调oauth的配置都不对,就对问题进行一个个简化拆分,一个问题一个问题的解决
场景一:nginx 80 代理 oauth-client 8082
有了nginx ,就会出现异常,那么从最简单的场景开始测试。
程序配置:
nginx 配置:
nginx.conf
1 2 3 4 5 6 7 8 9 10 11 12
|
server { listen 80; server_name blog.95id.com; port_in_redirect off; location / { add_header Cache-Control no-store; proxy_pass http://127.0.0.1:8082; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
|
查看请求重定向详情
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
curl -Lv http://blog.95id.com/user_attr
* 打印信息中有删减,保留跳转的信息
* Connected to blog.95id.com (212.64.15.210) port 80 (#0) > GET /user_attr HTTP/1.1 > Host: blog.95id.com
< HTTP/1.1 302 < Server: nginx/1.12.2 < Location: http://blog.95id.com/login < Cache-Control: no-store > GET /login HTTP/1.1 > Host: blog.95id.com
< HTTP/1.1 302 < Server: nginx/1.12.2 < Date: Tue, 14 Jan 2020 02:18:33 GMT < Location: https://github.com/login/oauth/authorize?client_id=da2eedb7fbffa926eeab&redirect_uri=http://blog.95id.com/login&response_type=code&state=ApP8wq > GET /login/oauth/authorize?client_id=da2eedb7fbffa926eeab&redirect_uri=http://blog.95id.com/login&response_type=code&state=ApP8wq HTTP/1.1 > Host: github.com .......
< HTTP/1.1 302 Found < Date: Tue, 14 Jan 2020 02:18:34 GMT < Content-Type: text/html; charset=utf-8 < Transfer-Encoding: chunked < Server: GitHub.com < Status: 302 Found < Location: https://github.com/login?client_id=da2eedb7fbffa926eeab&return_to=%2Flogin%2Foauth%2Fauthorize%3Fclient_id%3Dda2eedb7fbffa926eeab%26redirect_uri%3Dhttp%253A%252F%252Fblog.95id.com%252Flogin%26response_type%3Dcode%26state%3DApP8wq <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <link rel="dns-prefetch" href="https://github.githubassets.com">
|
跳转一切正常
场景二: 非80端口nginx 代理 oauth-client 8082
用 4005 端口 代理 oauth-client的8082
nginx配置
1 2 3 4 5 6 7 8 9 10 11 12
|
server { listen 4005; server_name blog.95id.com; port_in_redirect off; location / { add_header Cache-Control no-store; proxy_pass http://127.0.0.1:8082; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
|
这时候打印请求详情
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
curl -Lv http://blog.95id.com:4005/user_attr
# 请求 blog.95id.com:4005/user_attr * Connected to blog.95id.com (212.64.15.210) port 4005 (#0) > GET /user_attr HTTP/1.1 > Host: blog.95id.com:4005
# 重定向 blog.95id.com/login < HTTP/1.1 302 < Server: nginx/1.12.2 < Date: Tue, 14 Jan 2020 02:29:06 GMT < Location: http://blog.95id.com/login * Connected to blog.95id.com (212.64.15.210) port 80 (#1) > GET /login HTTP/1.1 > Host: blog.95id.com > User-Agent: curl/7.54.0 > Accept: */*
# 无法访问 blog.95id.com/login,缺少port,预期port 为 4005 < HTTP/1.1 502 Bad Gateway < Server: nginx/1.12.2
|
如果把 nginx 的port_in_redirect 配置设置为 on,结果也是一样的,这个跳转是oauth-client程序内 spring-security-oauth2 自动做的跳转,也就是spring-security-oauth2 未能正常拿到4005 这个端口
再来看应用程序日志(DEBUG模式下)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
2020-01-14 10:58:43.388 DEBUG 1918 --- [http-nio-8082-exec-7] o.a.tomcat.util.net.SocketWrapperBase : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@5fc01a1e:org.apache.tomcat.util.net.NioChannel@58241aaa:java.nio.channels.SocketChannel[connected local=/127.0.0.1:8082 remote=/127.0.0.1:43746]], Read from buffer: [0] 2020-01-14 10:58:43.388 DEBUG 1918 --- [http-nio-8082-exec-7] o.a.coyote.http11.Http11InputBuffer : Received [GET /user_attr HTTP/1.0 Host: blog.95id.com X-Real-IP: 208.76.1.123 X-Forwarded-For: 208.76.1.123 Connection: close User-Agent: curl/7.54.0 Accept: */* ] ... 2020-01-14 10:58:43.391 DEBUG 1918 --- [http-nio-8082-exec-7] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@9055e4a6: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS ... org.springframework.security.access.AccessDeniedException: Access is denied ... 2020-01-14 10:58:43.393 DEBUG 1918 --- [http-nio-8082-exec-7] o.s.s.w.s.HttpSessionRequestCache : DefaultSavedRequest added to Session: DefaultSavedRequest[http://blog.95id.com/user_attr] ... 2020-01-14 10:58:43.394 DEBUG 1918 --- [http-nio-8082-exec-7] s.w.a.DelegatingAuthenticationEntryPoint : No match found. Using default entry point org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint@1df284b4 2020-01-14 10:58:43.394 DEBUG 1918 --- [http-nio-8082-exec-7] o.s.s.web.DefaultRedirectStrategy : Redirecting to 'http://blog.95id.com/login'
|
从打印的日志看,因为user_attr
需要授权允许,所以跳转到 /login
。但是当时spring-security已经拿不到4005端口了
打印的request信息也证实了,4005丢失不见了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
{ "header": [ "host::blog.95id.com", "x-real-ip::208.76.1.123", "x-forwarded-for::208.76.1.123", .... ], "info": [ "method:GET", "uri:/print_request", "url:http://blog.95id.com/print_request", "context_path:", "IP:127.0.0.1", "ServerPort:80", "LocalPort:8082", "RemotePort:46856" ] }
|
经过查找几次尝试,解决方法是在nginx -server 中加入配置:
1
|
proxy_set_header Host $host:$server_port;
|
这时request信息中,ServerPort = 4005
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
{ "header": [ "host::blog.95id.com:4005", "x-real-ip::208.76.1.123", "x-forwarded-for::208.76.1.123", .... ], "info": [ "method:GET", "uri:/print_request", "url:http://blog.95id.com:4005/print_request", "context_path:", "IP:127.0.0.1", "ServerPort:4005", "LocalPort:8082", "RemotePort:53908" ] }
|
该方案解决了端口丢失的问题,接着解决 https 变成 http的问题
场景三:HTTS 443端口 代理 oauth-client 8082
443 是 ssl的默认端口,场景二修改监听端口,再加上 ssl的配置,nginx配置如下:
nginx配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
server { listen 443; ssl on; server_name blog.95id.com; index index.html index.htm index.php; add_header Timing-Allow-Origin "*"; add_header Access-Control-Allow-Origin "*"; port_in_redirect off; ssl_certificate /data/apps/wwwroot/Nginx/1_blog.95id.com_bundle.crt; ssl_certificate_key /data/apps/wwwroot/Nginx/2_blog.95id.com.key; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; ssl_prefer_server_ciphers on; location / { add_header Cache-Control no-store; proxy_pass http://127.0.0.1:8082; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
|
问题现象:
访问:https://blog.95id.com/user_attr
被redirect to :http://blog.95id.com/login
浏览器报 400异常(因为重定向的是http,没配80端口)
1 2
|
400 Bad Request The plain HTTP request was sent to HTTPS port
|
curl 超时(因为重定向的是http,没配80端口)
1 2 3 4
|
[root@VM_0_17_centos oauth]# curl -Lv https://blog.95id.com/user_attr * About to connect() to blog.95id.com port 80 (#0) * Trying 212.64.15.210... ^C
|
这样配置发现 https 被重定向到 http,并且htts默认的443端口,变成了http的默认端口80
解决方案:
在oauth-client 配置文件中
1 2 3 4
|
server.tomcat.remote-ip-header=x-forwarded-for server.tomcat.protocol-header=X-Forwarded-Proto #server.tomcat.protocol-header-https-value=https server.use-forward-headers=true
|
nginx 配置中加入
1
|
proxy_set_header X-Forwarded-Proto $scheme;
|
测试可行
最后nginx配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
server { listen 443; ssl on; server_name blog.95id.com; index index.html index.htm index.php; add_header Timing-Allow-Origin "*"; add_header Access-Control-Allow-Origin "*"; port_in_redirect off; ssl_certificate /data/apps/wwwroot/Nginx/1_blog.95id.com_bundle.crt; ssl_certificate_key /data/apps/wwwroot/Nginx/2_blog.95id.com.key; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; ssl_prefer_server_ciphers on; location / { add_header Cache-Control no-store; proxy_pass http://127.0.0.1:8082; #proxy_set_header Host $host; proxy_set_header Host $host:$server_port; 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; } }
|
场景四 HTTPS 非443端口代理oauth-client 8082
开启ssl,用4005端口代替默认端口443。并且沿用场景二的方案,便于将端口同时带过来,可是还是出问题了
问题现象
沿用场景三的解决方案,并且带了场景二的方案,发现还是无法重定向到oauth2-server进行登录
访问:https://blog.95id.com:4005/user_attr
最后被重定向到:https://blog.95id.com/login
nginx 配置和场景三类似,只是修改了端口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
server { listen 4005; ssl on; server_name blog.95id.com; index index.html index.htm index.php; add_header Timing-Allow-Origin "*"; add_header Access-Control-Allow-Origin "*"; port_in_redirect off; ssl_certificate /data/apps/wwwroot/Nginx/1_blog.95id.com_bundle.crt; ssl_certificate_key /data/apps/wwwroot/Nginx/2_blog.95id.com.key; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; ssl_prefer_server_ciphers on; location / { add_header Cache-Control no-store; proxy_pass http://127.0.0.1:8082; #proxy_set_header Host $host; proxy_set_header Host $host:$server_port; 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; } }
|
https 是被带过来了,但是 端口4005丢失了,浏览器报不是私密链接(因为443端口没配ssl),curl 报连接超时 443端口没做转发
在场景二中配置的
1
|
proxy_set_header Host $host:$server_port;
|
也在其中,但是还是未生效
解决方案
在nginx 配置中增加
1
|
proxy_set_header X-Forwarded-Port $server_port;
|
在oauth2-client 的配置文件application.properties中添加:
application.properties
1
|
server.tomcat.port-header=X-Forwarded-Port
|
改动后的nginx 配置如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
server { listen 4005; ssl off; server_name blog.95id.com; index index.html index.htm index.php; add_header Timing-Allow-Origin "*"; add_header Access-Control-Allow-Origin "*"; port_in_redirect off; ssl_certificate /data/apps/wwwroot/Nginx/1_blog.95id.com_bundle.crt; ssl_certificate_key /data/apps/wwwroot/Nginx/2_blog.95id.com.key; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; ssl_prefer_server_ciphers on; location / { add_header Cache-Control no-store; proxy_pass http://127.0.0.1:8082; #proxy_set_header Host $host; proxy_set_header Host $host:$server_port; 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-Port $server_port; } }
|
oauth-client 配置
1 2 3 4 5 6
|
server.tomcat.remote-ip-header=x-forwarded-for server.tomcat.protocol-header=X-Forwarded-Proto server.use-forward-headers=true server.tomcat.port-header=X-Forwarded-Port
server.port=8082
|
其他尝试
测试发现X-Forwarded-Port
这个配置是否能可以解决端口丢失的问题,那么是否能用来解决场景二的问题?回到场景二的配置
1 2 3 4 5
|
#关闭ssl ssl off; # Host 设置为不带port ,而是通过X-Forwarded-Port 传递 proxy_set_header Host $host; #proxy_set_header Host $host:$server_port;
|
oauth-client 配置保持和场景三方案一样
测试的nginx 配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
server { listen 4005; ssl off; server_name blog.95id.com; index index.html index.htm index.php; add_header Timing-Allow-Origin "*"; add_header Access-Control-Allow-Origin "*"; port_in_redirect off; ssl_certificate /data/apps/wwwroot/Nginx/1_blog.95id.com_bundle.crt; ssl_certificate_key /data/apps/wwwroot/Nginx/2_blog.95id.com.key; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; ssl_prefer_server_ciphers on; location / { add_header Cache-Control no-store; proxy_pass http://127.0.0.1:8082; proxy_set_header Host $host; #proxy_set_header Host $host:$server_port; 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-Port $server_port; } }
|
测试通过,也就是 proxy_set_header Host $host:$server_port;
可以通过X-Forwarded-Port
方案替代
场景五 双层nginx 转发 https协议头 port丢失
上述场景都是单层的nginx 环境,如果用上述配置放到线上(也就是开篇描述的现象),还是出了问题。
但是单层nginx的解决了,多层的还会远吗?而且经过这么多场景的模拟测试,该问题的本质也逐渐明了,就是nginx 在转发request过程中https和port丢失的问题,多层的情况就是要解决第一层nginx 到最内层的nginx 中一些参数的传递问题
第一层:nginx1 4005 (ssl、负载均配置在这)
第二层:nginx2 4005
第三层:oauth2-client 8082
问题现象
访问:https://blog.95id.com:4005/user_attr
最后被重定向到:http://blog.95id.com/login
那么经过这么多场景,能够很清晰的定位问题: 协议头和port在nginx 代理过程中丢失,最有可能是第一层nginx 到 第二层nginx 过程中丢失。
另外在最外层nginx 配置了场景4nginx的配置,port不丢失了,但是最终还是重定向到了 http://blog.95id.com:4005/login,https丢了
解决方案
两种解决方案:
两个方案均需要在外层的nginx 上将https 往下层传,所以都需要:
1 2 3 4 5
|
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-Port $server_port;
|
如果是多层,就是要将 schema 和 port 层层往下传
1)方案一:强制使用https
如果nginx服务并没有直接面向最终用户,而是在某些负载均衡/cdn后面,并且ssl证书是在这些负载均衡/cdn上面配置的,那么有可能会导致nginx无法正确获取客户端所使用的协议,从而导致无法将客户端使用的协议传递给最后面的应用程序。在这种情况下,可以修改nginx配置,强制通知服务使用https协议,也就是不使用 $scheme 变量,而是写死 https。
1 2
|
#proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto https;
|
2) 方案二:利用$http_x_forwarded_proto
变量
除了最外层的nginx ,其余层的nginx在的http 内配置:
1 2 3 4 5 6
|
map $http_x_forwarded_proto $thescheme{ default $http_x_forwarded_proto; '' $scheme; } # $http_x_forwarded_proto 不为空 $thescheme 取 $http_x_forwarded_proto # $http_x_forwarded_proto 为空 $thescheme 取$scheme
|
在转发服务的nginx -server 中配置:
1 2
|
#proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $thescheme;
|
Bingo !尝试大几十遍终于都可以了
终极配置方案
上述这些场景导致OAuth2-Client 无法正常使用,本质原因还是因为 request的schema 和port 无法下传到 应用程序导致的。如果java应用程序能正常拿到,就不存在这些问题,所以只需要解决,request从nginx到client,不丢失相关信息即可
通过这些配置,发现后面方案是可以兼容解决前面的场景,所以这里可以给个最终的配置方案
不管是 默认端口代理,还是开启Https ,还是层层代理,这个配置都可以使OAuth2Client 生效
1)在应用程序的主配置文件中加入:
1 2 3 4
|
server.tomcat.remote-ip-header=x-forwarded-for server.tomcat.protocol-header=X-Forwarded-Proto server.use-forward-headers=true server.tomcat.port-header=X-Forwarded-Port
|
2)在nginx 配置中,http模块下,加一个map设置thescheme
参数用来传递scheme,在代理服务的server配置中,加入header
相关配置(proxy_set_header
开头):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
http { map $http_x_forwarded_proto $thescheme{ default $http_x_forwarded_proto; '' $scheme; } ...... server { listen 4005; server_name 0.0.0.0;
location / { proxy_pass http://127.0.0.1:8082; 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 $thescheme; proxy_set_header X-Forwarded-Port $server_port; } ...... }
|
3)在springboot应用程序中加入如下配置
1 2 3 4
|
server.tomcat.remote-ip-header=x-forwarded-for server.tomcat.protocol-header=X-Forwarded-Proto server.use-forward-headers=true server.tomcat.port-header=X-Forwarded-Port
|
如果是非内嵌的tomcat , 则需要修改tomcat 的配置(无tomcat,未测试)
1 2 3 4 5
|
<!-- 放在<Valve className="org.apache.catalina.valves.AccessLogValve">的后面(同级关系)--> <Valve className="org.apache.catalina.valves.RemoteIpValve" remoteIpHeader="X-Forwarded-For" protocolHeader="X-Forwarded-Proto" portHeader="X-Forwarded-Port"/>
|
测试用的OAuth2-Client源码 和 nginx 最终配置方案可以见 https://github.com/ifengkou/oauth2-client-157
server.tomcat.port-header
设定http header使用的,用来覆盖原来port的value.
server.tomcat.protocol-header
设定Header包含的协议,通常是 X-Forwarded-Proto,如果remoteIpHeader有值,则将设置为RemoteIpValve.
server.tomcat.protocol-header-https-value
设定使用SSL的header的值,默认https.
server.tomcat.remote-ip-header
设定remote IP的header,如果remoteIpHeader有值,则设置为RemoteIpValve
server.use-forward-headers=true
该配置将指示tomcat从HTTP头信息中去获取协议信息(而非从HttpServletRequest中获取),同时,如果你的应用还用到了spring-security则也无需再配置。
补习Java 程序获得相关请求信息
可以具体见Oauth2-client 项目中 Oauth2Client157Application文件内的 printRequest方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
List<String> headerInfo = new ArrayList<>(); //获得所有的头的名称 Enumeration<String> headerNames = request.getHeaderNames(); while(headerNames.hasMoreElements()){ String headerName = headerNames.nextElement(); String headerValue = request.getHeader(headerName); headerInfo.add(headerName+"::"+headerValue); } List<String> urlInfo = new ArrayList<>(); urlInfo.add("method:" + request.getMethod()); urlInfo.add("uri:" + request.getRequestURI()); urlInfo.add("url:" + request.getRequestURL()); urlInfo.add("ServerPort:" + request.getServerPort()); urlInfo.add("LocalPort:" + request.getLocalPort()); urlInfo.add("serverName:"+request.getServerName()); urlInfo.add("schema:"+request.getScheme());
|
访问:https://blog.95id.com:4005/print_request
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
{ "header": [ "host::blog.95id.com", "x-real-ip::213.123.1.2", "x-forwarded-proto::https", "x-forwarded-port::4005", ...... ], "info": [ "method:GET", "uri:/print_request", "url:https://blog.95id.com:4005/print_request", "context_path:", "IP:213.123.1.2", "ServerPort:4005", "LocalPort:8082", "RemotePort:37516", "serverName:blog.95id.com", "schema:https" ] }
|
补习 Nginx 参数配置
nginx ssl 证书配置
1 2 3 4 5 6 7 8
|
ssl on; ssl_certificate /data/apps/wwwroot/Nginx/1_blog.95id.com_bundle.crt; ssl_certificate_key /data/apps/wwwroot/Nginx/2_blog.95id.com.key; ssl_session_timeout 5m; ssl_session_cache shared:SSL:10m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; ssl_prefer_server_ciphers on;
|
配置自动获取协议方式
通过这种方式配置,客户端可以使用http或者https协议,应用服务能够自动获取客户端使用的协议。
配置nginx 反向代理 proxy_set_header 。 在server里面,增加下面的配置:
1 2 3 4 5 6 7 8 9
|
server { proxy_set_header X-Real-IP $remote_addr; proxy_set_header x-wiz-real-ip $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Port $server_port; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Proto $scheme; ... }
|
如果您的nginx有多层,那么,您可能还需要额外的配置: 在http 模块中加入以下配置:
1 2 3 4
|
map $http_x_forwarded_proto $thescheme{ default $http_x_forwarded_proto; '' $scheme; }
|
然后在server模块(或者http模块)里面,将前面配置中的proxy_set_header X-Forwarded-Proto $scheme;
,替换为下面的代码:
1
|
proxy_set_header X-Forwarded-Proto $thescheme;
|
如果您的nginx服务,并没有直接面向最终用户,而是在某些负载均衡/cdn后面,并且您的ssl证书是在这些负载均衡/cdn上面配置的,那么有可能会导致nginx无法正确获取客户端所使用的协议,这时可以强制https
1
|
proxy_set_header X-Forwarded-Proto "https";
|
标签:set,
https,
header,
server,
nginx,
proxy,
搬运,
com,
id
From: https://www.cnblogs.com/beilong/p/17040094.html