Spring Web应用部署至域名服务器后WebSocket连接403失败排查
Spring Web应用WebSocket部署后403连接失败问题
问题描述
本地运行Spring Web应用时WebSocket连接可正常建立,但部署到域名服务器(merkeido.com)后连接失败,浏览器控制台报错:WebSocket connection to 'wss://merkeido.com/ws/776/1lq4jnfq/websocket' failed:
额外信息
- 本地运行无异常,仅部署到服务器后出现问题
- 服务器返回**403(Forbidden)**状态码
- WebSocket端点:
wss://merkeido.com/ws/776/1lq4jnfq/websocket
已尝试操作
- 确认Spring配置中已启用WebSocket支持
- 验证WebSocket端点URL及配置正确性
- 检查服务器日志中的相关错误信息
核心问题
部署后导致WebSocket连接返回403禁止错误的可能原因是什么?请提供故障排查的见解或建议。
WebSocket配置代码
@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker("/user"); config.setApplicationDestinationPrefixes("/app"); config.setUserDestinationPrefix("/user"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/ws").withSockJS(); } }
前端HTML/JavaScript代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.1.4/sockjs.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"></script> <script th:inline="javascript"> 'use strict'; let stompClient = null; let selectedUserId = null; let userId = user_id; connect(); function connect() { const socket = new SockJS('/ws'); stompClient = Stomp.over(socket); stompClient.connect({}, onConnected, onError); } function onConnected() { stompClient.subscribe(`/user/${userId+""}/queue/messages`, onMessageReceived); stompClient.subscribe(`/user/public`, onMessageReceived); // 注册在线用户 stompClient.send("/app/user.addUser", {}, JSON.stringify({id: userId+"", c_status: 'ONLINE'}) ); findAndDisplayConnectedUsers().then(); } </script>
控制台完整错误日志
Opening Web Socket... websocket.js:6 WebSocket connection to 'wss://merkeido.com/ws/776/1lq4jnfq/websocket' failed: e.exports @ websocket.js:6 /ws/776/in3mqa1z/xhr_streaming?t=1714645083452:1 Failed to load resource: the server responded with a status of 403 () stomp.min.js:8 Web Socket Opened... stomp.min.js:8 >>> CONNECT accept-version:1.1,1.0 heart-beat:10000,10000
故障排查建议
1. 跨域(CORS)配置缺失
本地开发时浏览器同源策略限制宽松,线上部署后需明确配置WebSocket允许的域名,否则会触发403。修改WebSocket配置:
@Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/ws") .setAllowedOriginPatterns("https://merkeido.com") // 生产环境指定具体域名,测试可临时用"*" .withSockJS(); }
2. Spring Security拦截WebSocket请求
若项目集成Spring Security,需手动放行WebSocket相关路径,避免被权限拦截:
@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/ws/**") .permitAll() .anyRequest().authenticated(); // 禁用WebSocket路径的CSRF校验 http.csrf().ignoringAntMatchers("/ws/**"); } }
3. 反向代理/服务器防火墙拦截
- Nginx配置问题:若用Nginx做反向代理,需添加WebSocket支持的头转发规则:
location /ws { proxy_pass http://你的后端服务地址; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; } - 防火墙/WAF限制:检查服务器防火墙、云服务商WAF是否拦截了WebSocket请求,确保443端口(wss协议)正常开放,且未拦截
Upgrade请求头。
4. SockJS降级路径未放行
错误日志显示XHR流请求也返回403,说明SockJS的降级路径同样被拦截,需确保服务器放行所有/ws/**下的子路径。
5. 应用上下文路径不匹配
若线上应用部署在子路径下(如https://merkeido.com/your-app),前端SockJS连接路径需调整为完整路径:
const socket = new SockJS('/your-app/ws');
6. SSL证书异常
使用wss协议时,若服务器SSL证书无效(自签名、过期、域名不匹配),浏览器可能间接返回403,可通过浏览器地址栏查看证书状态确认有效性。
内容的提问来源于stack exchange,提问作者DEXA
相关产品推荐
相关产品推荐

