Spring WebSocket 返回未记录的 403
Posted
技术标签:
【中文标题】Spring WebSocket 返回未记录的 403【英文标题】:Spring WebSocket returning an unlogged 403 【发布时间】:2015-11-17 03:51:15 【问题描述】:我的 Spring WebSocket 返回了 403,但我不确定为什么,Spring Security 当前不在类路径中。
注意:我开始写这个问题,然后打开了完整的 Spring Boot 调试,这是它发出的最后 3 行日志。
2015-08-23 14:38:30.263 DEBUG 32271 --- [nio-8080-exec-1] o.s.b.a.e.mvc.EndpointHandlerMapping : Looking up handler method for path /socket/info
2015-08-23 14:38:30.270 DEBUG 32271 --- [nio-8080-exec-1] o.s.b.a.e.mvc.EndpointHandlerMapping : Did not find handler method for [/socket/info]
2015-08-23 14:39:08.791 INFO 32271 --- [eBrokerSockJS-1] o.s.w.s.c.WebSocketMessageBrokerStats : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannelpool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
这是响应标头
HTTP/1.1 403 Forbidden
Server: Apache-Coyote/1.1
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Allow-: POST, GET, PUT, OPTIONS, DELETE
Access-Control-Allow-Headers: content-type, x-auth-token, x-requested-with
Access-Control-Expose-Headers: Location
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 3600
X-Application-Context: application
Cache-Control: no-store, no-cache, must-revalidate, max-age=0
Content-Length: 0
Date: Sun, 23 Aug 2015 18:01:10 GMT
这是请求
GET /socket/info?t=1440352870279 HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Origin: http://localhost:3000
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/44.0.2403.157 Safari/537.36
Accept: */*
DNT: 1
Referer: http://localhost:3000/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Cookie: NXSESSIONID=174bf31b-e199-44e3-bae8-f5f44ad6ee90
这是我的 WebSocket 配置
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer
@Override
public void configureMessageBroker( final MessageBrokerRegistry config )
config.enableSimpleBroker( "/topic" );
config.setApplicationDestinationPrefixes( "/app" );
@Override
public void registerStompEndpoints( final StompEndpointRegistry registry )
registry.addEndpoint( "/socket" ).withSockJS();
访问http://localhost:8080 会显示“欢迎使用 SockJS!”所以我相信这是有效的。 StompJS 在 403 之后发出 Whoops! Lost connection to http://localhost:8080/socket
。
这是我的 javascript。
var SockJS = require( 'sockjs-client' );
var sock = new SockJS( 'http://localhost:8080/socket' );
var Stomp = require( 'stompjs' );
var stompClient = Stomp.over( sock );
stompClient.connect( , function( frame )
console.log( 'Connected: ' + frame );
stompClient.subscribe( '/topic/stations/create', function()
console.log( 'subscribed' );
);
);
stomp 发出这个Opening Web Socket...
,但从未连接
我错过了什么?我做错了什么?
【问题讨论】:
【参考方案1】:显然,我需要允许第二个允许来源,特别是对于 websockets。我的application.properties
中有一个allowOrigin
,然后在我的配置中使用了setter 注入,因为构造函数注入不适用于这种bean 类型。然后在调用withSockJs
之前,我只需要添加setAllowedOrigins( ... )
。
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer
private URI allowOrigin;
@Inject // constructor injection not working in this class, use setter injection instead
public void setAllowOrigin( @Value( "$allowOrigin" ) final URI allowOrigin )
this.allowOrigin = Objects.requireNonNull( allowOrigin );
@Override
public void configureMessageBroker( final MessageBrokerRegistry config )
config.enableSimpleBroker( "/topic" );
config.setApplicationDestinationPrefixes( "/app" );
@Override
public void registerStompEndpoints( final StompEndpointRegistry registry )
registry.addEndpoint( "/socket" )
.setAllowedOrigins( allowOrigin.toString() )
.withSockJS();
【讨论】:
以上是关于Spring WebSocket 返回未记录的 403的主要内容,如果未能解决你的问题,请参考以下文章
Spring 4 websocket和stomp - 未到达控制器
Spring Websocket ChannelInterceptor 未触发 CONNECT 事件