相关疑难解决方法(0)

带有基于Spring的SockJS/STOMP Web Socket的JSON Web令牌(JWT)

背景

我正在使用包含STOMP/SockJS WebSocket的Spring Boot(1.3.0.BUILD-SNAPSHOT)设置RESTful Web应用程序,我打算从iOS应用程序和Web浏览器中使用它.我想使用JSON Web令牌(JWT)来保护REST请求和WebSocket接口,但我对后者有困难.

该应用程序使用Spring Security进行保护: -

@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    public WebSecurityConfiguration() {
        super(true);
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("steve").password("steve").roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .exceptionHandling().and()
            .anonymous().and()
            .servletApi().and()
            .headers().cacheControl().and().and()

            // Relax CSRF on the WebSocket due to needing direct access from apps
            .csrf().ignoringAntMatchers("/ws/**").and()

            .authorizeRequests()

            //allow anonymous resource requests
            .antMatchers("/", "/index.html").permitAll()
            .antMatchers("/resources/**").permitAll()

            //allow anonymous POSTs to JWT
            .antMatchers(HttpMethod.POST, "/rest/jwt/token").permitAll()

            // Allow anonymous …
Run Code Online (Sandbox Code Playgroud)

spring spring-security websocket jwt sockjs

44
推荐指数
4
解决办法
3万
查看次数

哪个"user"来自convertAndSendToUser在SockJS + Spring Websocket中工作?

我想了解convertAndSendToUser如何在Spring SockJS + Websocket框架中工作.

在客户端,我们将连接为

stompClient.connect(login, password, callback())
Run Code Online (Sandbox Code Playgroud)

这将导致连接请求与登录和密码的"Stomp凭证",例如,如果我们处理SessionConnectEvent http://www.sergialmar.com/2014/03/detect-websocket-connects-and-disconnects-in -spring-4 /

但我仍然不清楚这是否是服务器端向队列发送操作的"用户":

 simpMessagingTemplate.convertAndSendToUser(username, "/queue/reply", message);
Run Code Online (Sandbox Code Playgroud)

我能得到的最接近的是阅读这个帖子向Spring Websocket上的特定用户发送消息,由Thanh Nguyen Van回答,但目前还不清楚.

基本上我需要做的是订阅一些客户端到同一主题,但在服务器上,发送不同的数据.客户可以提供用户标识符.

java spring stomp sockjs spring-websocket

24
推荐指数
1
解决办法
8911
查看次数

为什么SimpUserRegistry在EC2实例上无法正常工作

SimpUserRegistry用来获取在线用户数(带getUserCount()).它在我的本地机器上运行良好,但在AWS EC2实例(使用Amazon Linux和Ubuntu试用)上只有弹性IP且没有负载均衡器.

EC2上的问题是,某些用户在连接时从未添加到注册表中,因此我得到错误的结果.

我有会话监听器,为SessionConnectedEventSessionDisconnectEvent,在这里我使用SimpUserRegistry(自动装配Autowired)来获得用户的存在.如果重要的话,我也是SimpUserRegistry一个消息传递控制器.

以下是websocket消息代理配置:

@Order(Ordered.HIGHEST_PRECEDENCE + 99)
@Configuration
@EnableWebSocketMessageBroker
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class WebSocketMessageBrokerConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @NonNull
    private SecurityChannelInterceptor securityChannelInterceptor;

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
        threadPoolTaskScheduler.setPoolSize(1);
        threadPoolTaskScheduler.setThreadGroupName("cb-heartbeat-");
        threadPoolTaskScheduler.initialize();

        config.enableSimpleBroker("/queue/", "/topic/")
                .setTaskScheduler(threadPoolTaskScheduler)
                .setHeartbeatValue(new long[] {1000, 1000});

        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/websocket")
                .setAllowedOrigins("*")
                .withSockJS();
    }

    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration.interceptors(securityChannelInterceptor);
    }
}
Run Code Online (Sandbox Code Playgroud)

以下是上面配置类中使用的通道拦截器:

@Slf4j …
Run Code Online (Sandbox Code Playgroud)

java amazon-ec2 websocket spring-messaging spring-websocket

8
推荐指数
1
解决办法
671
查看次数

Spring安全websocket和HTTP身份验证/授权

总结 我想通过STOMP实现websocket通信.在第一次(HTTP请求)websocket握手时验证用户,并使用此Principal稍后授权websocket消息.

问题 系统在第一次尝试连接到websocket端点(HTTP握手的时间)时对客户端进行身份验证.我的Spring安全过滤器和身份验证提供程序完成其工作并正确验证客户端.在此之后,我可以检查客户端是否获得了角色,我的身份验证对象也存储在SecurityContext中.(此时已建立websocket连接,并且已丢弃HTTP协议.)但是,从第一个websocket通信我得到Authentication对象是Anonymous,因为SecurityContextHolder以某种方式被清除,因为SecurityContextChannelInterceptor清除它.

Spring文档声明如下:http://docs.spring.io/autorepo/docs/spring-security/current/reference/htmlsingle/#websocket-authentication

WebSockets重用与WebSocket连接时在HTTP请求中找到的相同身份验证信息.这意味着HttpServletRequest上的Principal将被移交给WebSockets.如果您使用的是Spring Security,则会自动覆盖HttpServletRequest上的Principal.

我非常简单的过滤器

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {

    try {


        Authentication authResult =
                new CertAuthenticationToken(null, Arrays.asList(new SimpleGrantedAuthority("ROLE_ADMIN")));

        authResult = getAuthenticationManager().authenticate(authResult);

        if (authResult.isAuthenticated()) {
            SecurityContextHolder.getContext().setAuthentication(authResult);
            LOGGER.info("Client was authenticated.");
        }
        chain.doFilter(request, response);

    } catch (AuthenticationException ae) {
        LOGGER.error("Client was not authenticated. {}", ae);
        SecurityContextHolder.clearContext();
        onUnsuccessfulAuthentication((HttpServletRequest) request, (HttpServletResponse) response, ae);
        throw ae;
    }
}
Run Code Online (Sandbox Code Playgroud)

我非常简单的认证提供商

 public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        authentication.setAuthenticated(true);
        return …
Run Code Online (Sandbox Code Playgroud)

spring spring-security spring-boot spring-messaging spring-websocket

7
推荐指数
0
解决办法
5983
查看次数

如何为 spring 5 websocket 添加安全性

我遵循以下教程:使用 WebSocket 构建交互式 Web 应用程序

一切都按照描述进行,并且应用程序看起来很好。我只有一个很好的控制器:

@Controller
public class GreetingController {    

    @MessageMapping("/hello")
    @SendTo("/topic/greetings")
    public Greeting greeting(HelloMessage message) throws Exception {
        Thread.sleep(1000); // simulated delay
        return new Greeting("Hello, " + HtmlUtils.htmlEscape(message.getName()) + "!");
    }

}
Run Code Online (Sandbox Code Playgroud)

还有一点配置。

现在我想为这个简单的应用程序添加安全性。我花了时间找例子,但找不到。

一般来说,我找到了教程:

预览 Spring Security WebSocket 支持

但看起来这个例子只与 spring 4 相关,而不是 spring 5。而且我不明白我应该在哪里提供凭据等。描述不够详细,无法应用于我的示例。

我发现了另外一个教程: Websocket Authentication and Authorization in Spring Ask

它看起来更清晰,但我不确定它是目前最好的解决方案。

您能建议为我的应用程序配置 spring security 的最简单方法吗?

PS我还发现了不一样但熟悉的问题How to secure websocket application [Spring boot + STOMP],但目前没有答案。

locus2k的更新

现在我有以下配置:

@Configuration
@EnableWebSocketMessageBroker
public …
Run Code Online (Sandbox Code Playgroud)

java spring spring-security websocket spring-boot

7
推荐指数
1
解决办法
7833
查看次数

如何在Spring websocket的SessionDisconnectEvent中使用sessionId

我正在尝试用侦听器捕获SessionDisconnectEvent事件:


    @Component
public class WebSocketDisconnectListener implements ApplicationListener {

    @Override
    @EventListener
    public void onApplicationEvent(SessionDisconnectEvent event) {
        Principal principal = event.getUser();
        logger.info("websocket disconnected {}, user {}", event, principal);
        if (principal != null) {
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但本金始终为空。所以我发现SessionDisconnectEvent有一个名为 的事件sessionId,但是我该如何使用呢sessionId

哪里可以获得会议或校长?

spring websocket

5
推荐指数
1
解决办法
1987
查看次数