经过身份验证的 Web 套接字 Spring Boot 3

问题描述 投票:0回答:0

我和我的团队一直在尝试使用 Spring Security 6 迁移到 Spring boot 3,但发现网络套接字存在问题。如果我们删除

@EnableWebSocketSecurity
注释一切正常,但关键是只允许经过身份验证的消息。

添加注释时,我们得到的只是前端的

ExecutorSubscribableChannel[clientInboundChannel]
错误和后端的
access denied

我们还尝试按照官方文档 [https://docs.spring.io/spring-security/reference/servlet/integrations/websocket.html#websocket-sameorigin-csrf] 中的说明添加 csrf 令牌,但唯一的我们得到的是

The request object has been recycled and is no longer associated with this facade
错误消息。

就我们完全迷路而言,我们将感谢任何帮助:(

这里是关于我们的配置以及我们如何尝试创建连接的更多详细信息:

安全配置

@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true)
internal class OpaqueTokenSecurityConfig {
    @Value("\${spring.security.oauth2.client.provider.abc.token-uri}")
    var tokenUri: String? = null

    @Value("\${spring.security.oauth2.client.registration.abc.clientId}")
    var clientId: String? = null

    @Value("\${spring.security.oauth2.client.registration.abc.clientSecret}")
    var clientSecret: String? = null

    @Bean
    fun customIntrospector(): OpaqueTokenIntrospector {
        return CustomAuthoritiesOpaqueTokenIntrospector("$tokenUri/introspect", clientId, clientSecret)
    }

    @Bean
    fun filterChain(http: HttpSecurity): SecurityFilterChain? {
        http
            .csrf().disable()
            .sessionManagement().sessionCreationPolicy((SessionCreationPolicy.STATELESS))
            .and()
            .authorizeHttpRequests().anyRequest().authenticated()
            .and()
         .exceptionHandling().authenticationEntryPoint(HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
            .and()
            .oauth2ResourceServer()
            .opaqueToken()
            .introspector(customIntrospector())

        return http.build()
    }

    @Bean
    fun corsConfigurer(): WebMvcConfigurer {
        return object : WebMvcConfigurer {
            override fun addCorsMappings(registry: CorsRegistry) {
                registry.addMapping("/**")
                    .allowedOrigins("*")
                    .allowedMethods("*")
            }
        }
    }
}

WebSocketsConfig

@Configuration
@EnableWebSocketMessageBroker
@EnableWebSocketSecurity
internal class WebSocketConfig : WebSocketMessageBrokerConfigurer {
    override fun configureMessageBroker(config: MessageBrokerRegistry) {
        config
            .enableSimpleBroker("/topic")
    }

    override fun registerStompEndpoints(registry: StompEndpointRegistry) {
        registry
            .addEndpoint("/ws")
            .setAllowedOriginPatterns("*")

    }

    @Configuration
    open class WebSocketSecurityConfig {
        fun messageAuthorizationManager(messages: MessageMatcherDelegatingAuthorizationManager.Builder): AuthorizationManager<Message<*>> {
            messages
                .anyMessage().authenticated()

            return messages.build();
        }
    }
}

React 客户端:

let socket: CompatClient;
const client = Stomp.over(() => new WebSocket(`ws://localhost:8081/ws?access_token=${keycloak.token}`));
      
      client.onWebSocketClose = () => {
        // Do something
      };

      client.connect(
        {},
        () => {
          socket = client;
          // Do something
        },
        // eslint-disable-next-line no-console
        (err: unknown) => console.log(err),
      );
spring-boot spring-security websocket stomp
© www.soinside.com 2019 - 2024. All rights reserved.