SpringMVC Websockets 使用 Spring Security 进行用户身份验证消息传递

2023-11-28

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

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

这是有效的:

  1. 我可以在客户端和服务器之间进行精彩的来回通信
  2. 它很快
  3. messagingTemplate.convertAndSend and messagingTemplate.convertAndSendToUser

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

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

开放式 WebSocket 连接存在哪些安全问题?

具有stomp安全性的Spring websocket - 每个用户都可以订阅任何其他用户队列?

Websocket:如何向目标用户推送消息

问题是这样的:

  • Look at messagingTemplate.convertAndSendToUser- 所做的就是添加“用户前缀”,然后添加提供的用户名,然后使用messagingTemplate.convertAndSend这不适用安全性。

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

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

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


新的 Spring Security 4x 现在完全支持 Web Socket,您可以参考链接预览 Spring Security WebSocket 支持

Or SpringSecuritySupportWebSocket.html如果您需要完整的示例,

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringMVC Websockets 使用 Spring Security 进行用户身份验证消息传递 的相关文章

随机推荐