我看过几个关于这个问题的话题,但似乎没有一个能真正直接回答这个问题。

背景,我安装了 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); 
 
 
    } 
 
 
} 

好的,现在这是一个 Controller ,每 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> 

这是有效的:

  1. 我可以在客户端和服务器之间产生出色的来回通信
  2. 速度很快
  3. messagingTemplate.convertAndSendmessagingTemplate.convertAndSendToUser

这就是问题所在(如上所述):任何人都可以订阅其他用户的提要。

现在,还有一些其他的版本,我将在下面列出它们,并解释为什么答案都是错误的:

What are the security issues around an open websocket connection?

Spring websocket with stomp security - every user can subscribe to any other users queue?

Websocket: How To Push A Message To A Target User

问题是:

  • 查看 messagingTemplate.convertAndSendToUser - 所做的只是添加“用户前缀”,然后添加提供的用户名,然后使用 messagingTemplate.convertAndSend申请安全。

  • 然后人们说“你需要像其他任何地方一样使用 spring security”——这里的问题是 A) 我正在异步地向客户端发送数据,所以 B) 我将完全在外部使用这段代码用户的 session ,可能来自不同的用户(比如向另一个登录用户发送通知)。

让我知道这是否与其他帖子关系过于密切,但这对我来说是个大问题,我想公正对待。

如果有人需要更多详细信息,我可以获取更多详细信息。

请您参考如下方法:

新的 Spring Security 4x 现在完全支持 Web Socket,您可以引用链接 Preview Spring Security WebSocket Support

SpringSecuritySupportWebSocket.html如果你需要一个完整的例子,


评论关闭
IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!