使用Spring Security的SpringMVC Websockets消息传递用户身份验证
问题内容:
我已经看到了几个有关此问题的线索,但似乎没有一个人真的直接回答了这个问题。
背景知识,我已经在应用程序的其他部分中安装了Spring Security,并可以正常运行。我的用户名是“开发人员”。
在Java 7,Glassfish 4,Spring 4上运行,并使用Angular + StompJS
让我们在这里获取一些代码:
package com.myapp.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketBrokerConfig extends AbstractWebSocketMessageBrokerConfigurer {
public final static String userDestinationPrefix = "/user/";
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/stomp").withSockJS().setSessionCookieNeeded(true);
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/app");
//registry.enableStompBrokerRelay("/topic,/user");
registry.enableSimpleBroker("/topic", "/user");
registry.setUserDestinationPrefix(userDestinationPrefix);
}
}
好的,这是一个控制器,每3秒发送一次:
import org.springframework.messaging.simp.SimpMessagingTemplate;
…
@Autowired
private SimpMessagingTemplate messagingTemplate;
…
@Scheduled(fixedDelay = 3000)
public void sendStuff ()
{
Map<String, Object> map = new HashMap<>();
map.put(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON);
System.out.print("Sending data! " + System.currentTimeMillis());
//messagingTemplate.convertAndSend("/topic/notify", "Public: " + System.currentTimeMillis());
messagingTemplate.convertAndSendToUser("developer", "/notify", "User: " + System.currentTimeMillis());
messagingTemplate.convertAndSendToUser("notYou", "/notify", "Mr Developer Should Not See This: " + System.currentTimeMillis());
}
最后是使用SockJS的JavaScript
var client = new SockJS('/stomp');
var stomp = Stomp.over(client);
stomp.connect({}, function(s) {
//This should work
stomp.subscribe('/user/' + s.headers['user-name'] + '/notify', console.debug);
//This SHOULD NOT
stomp.subscribe('/user/notYou/notify', console.debug);
});
client.onclose = $scope.reconnect;
最后,pom.xml值得一提
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<version>4.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>4.0.6.RELEASE</version>
</dependency>
这是起作用的:
- 我可以在客户端和服务器之间进行美妙的来回通信
- 它很快
messagingTemplate.convertAndSend
和messagingTemplate.convertAndSendToUser
这是问题(上面已指出):任何人都可以订阅其他用户的feed。
这是问题所在:
-
看一下
messagingTemplate.convertAndSendToUser
-所要做的只是添加“用户前缀”,然后添加提供的用户名,然后使用messagingTemplate.convertAndSend
不适用安全性的用户名。 -
然后人们说“您需要像其他地方一样使用spring安全性”-这里的问题是A)我正在异步向客户端发送数据,因此B)我将在用户会话之外完全使用此代码来自另一个用户(例如向另一个登录用户发送通知)。
让我知道这是否与其他职位关系太紧密,但是对我来说这是一个大问题,我想做到这一点。
如果有人需要更多详细信息,我可以获取更多详细信息。
问题答案:
新的Spring Security 4x现在完全支持Web Socket,您可以参考链接预览Spring Security
WebSocket支持
或者,如果需要完整的示例,请使用SpringSecuritySupportWebSocket.html,