我在Spring MVC应用程序中集成了WebSockets。我的应用程序的身份验证机制是OAuth。
连接到SockJS时,我能够在连接字符串中传递OAuth令牌:
var webSocketUrl = '/websocket' + '?access_token=' + auth.access_token;
var socket = new SockJS(webSocketUrl);
var stompClient = Stomp.over(socket);
现在我可以发送消息并订阅STOMP频道:
stompClient.connect({}, function(frame) {
stompClient.subscribe('/topic/greetings', function(greeting){
console.log(greeting);
});
stompClient.send("/app/hello", {}, JSON.stringify('John'));
});
在我的后端,我能够将用户原则注入到我的STOMP控制器方法中(这意味着Spring了解连接字符串中有OAuth令牌):
@Controller
public class MyWebsocketsController {
@MessageMapping("/hello")
@SendTo("/topic/greetings")
public String greet(String name, Principal authorizedUser) {
return "Hello, " + name + ", you have authorized as " + authorizedUser.getName();
}
}
现在我想要对所有消息和订阅都要求用户授权,即如果连接到SockJS时没有提供有效的令牌,我想确保所有对Web套接字的调用都返回403错误代码。
我将此安全配置添加到我的项目中:
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
@Override
protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
messages
.simpTypeMatchers(CONNECT, HEARTBEAT, UNSUBSCRIBE, DISCONNECT).permitAll()
.simpDestMatchers("/app/**").authenticated()
.simpSubscribeDestMatchers("/topic/**").authenticated()
.simpTypeMatchers(MESSAGE, SUBSCRIBE).denyAll()
.anyMessage().denyAll();
}
}
但它似乎没有完成这项工作。如果我从连接字符串中删除访问令牌,我仍然可以向控制器发送消息并订阅频道。
// This stil works:
var webSocketUrl = '/websocket'; // + '?access_token=' + auth.access_token;
当然,现在我无法在我的控制器中获得用户原则,但除了这个Web套接字工作正常。
我很感激任何想法如何使这个东西工作或任何解释为什么Web套接字安全配置不适用于我的情况。我错过了什么?感谢。