王磊的个人博客   Java技术博客

life is painful
life is beautiful!

webSocket通过Nginx代理时响应403 有更新!

场景

项目中使用了websocket协议,开始是直接tomcat部署,没有问题,后来需要改为https协议,用Nginx来代理服务,出现websocket握手时返回403,根据网上的配置如下

server {
    listen 443;
    server_name carmonitor.win-sky.com.cn;
    ssl on;
    ssl_certificate /etc/win-sky.crt;
    ssl_certificate_key /etc/win-sky.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers AESGCM:ALL:!DH:!EXPORT:!RC4:+HIGH:!MEDIUM:!LOW:!aNULL:!eNULL;
    ssl_prefer_server_ciphers on;
    location / {
       proxy_pass http://172.16.0.18:8080;
       proxy_redirect off;
       proxy_http_version 1.1;
       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection "upgrade";
    }
}

websocket测试代码为在浏览器的console中输入  new WebSocket('wss://192.168.10.61/')执行测试;

解决方案


如果想使用Websocket和Spring Security,Nginx需要传递一些额外的头值。 以下行需要添加到您的Nginx配置中的location section

增加配置如下

    # Pass the csrf token (see https://de.wikipedia.org/wiki/Cross-Site-Request-Forgery)
    # Default in Spring Boot and required. Without it nginx suppresses the value
 proxy_pass_header X-XSRF-TOKEN;

    # Set origin to the real instance, otherwise a of Spring security check will fail
    # Same value as defined in proxy_pass
 proxy_set_header Origin "http://testsysten:8080";  

 websocket和跨域冲突解决方案

由于websocket需要配置请求源为web容器的请求路径,但是跨域需要设置请求源为*允许所有地址的请求或者设置允许的特定的域名,两者不一致,最终通过配置两种location解决。

location /webSocketServer {
  proxy_pass http://192.168.10.61:8080;
  proxy_redirect off;

  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";
  proxy_pass_header X-XSRF-TOKEN;
  proxy_set_header Origin "http://192.168.10.61:8080;";
}
location / {
  proxy_pass http://192.168.10.61:8080;
  proxy_redirect off;
  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 Access-Control-Allow-Origin *;
  proxy_set_header Access-Control-Allow-Methods POST,GET,DELETE,PUT,OPTIONS;
  proxy_set_header Access-Control-Allow-Headers X-Requested-With;
}

 

天堂未必在前方,但地狱一定在身后!
validate
Copyright (c) 2009-2017, b3log.org & hacpai.com