Springboot - websocket 未经授权的 401 与 JWT 身份验证

Springboot - websocket unauthorized 401 with JWT authentication

在我的项目中,我通过 JWT 令牌对登录用户进行身份验证。我也在为聊天模块创建网络套接字,但我无法与后端建立连接(我的前端很好,我可以连接到我发现的示例 here。在作者代码中,聊天和身份验证是单独的 springboot 项目,而我想将它放在一个地方。 我已经配置了 WebSecurityConfig


@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;

    @Autowired
    private UserDetailsService jwtUserDetailsService;

    @Autowired
    private JwtRequestFilter jwtRequestFilter;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(jwtUserDetailsService).passwordEncoder(passwordEncoder());
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
                .csrf().disable()
                .authorizeRequests().antMatchers(HttpMethod.OPTIONS).permitAll()
                .and()
                .authorizeRequests().antMatchers("/authenticate").permitAll().
                and().
                authorizeRequests().antMatchers("/ws").permitAll().
                // ...
               anyRequest().authenticated().
               and().
exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and().sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    }
}

我的 websocket 配置文件:


@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/user");
        config.setApplicationDestinationPrefixes("/app");
        config.setUserDestinationPrefix("/user");
    }

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

    @Override
    public boolean configureMessageConverters(List<MessageConverter> messageConverters) {
        DefaultContentTypeResolver resolver = new DefaultContentTypeResolver();
        resolver.setDefaultMimeType(MimeTypeUtils.APPLICATION_JSON);
        MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
        converter.setObjectMapper(new ObjectMapper());
        converter.setContentTypeResolver(resolver);
        messageConverters.add(converter);
        return false;
    }
}

我这里也配置了 CORS:

@Configuration
public class CorsConfig {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**").allowedMethods("GET", "POST", "PUT", "DELETE")
                        .allowCredentials(true) //edited, added this.
                        .allowedHeaders("*")
                        .allowedOrigins("*");
            }
        };
    }
}

如您所见,我想我已经处理了 cors 工作所需的东西,headers 和来源是允许的,添加了 authorizeRequests().antMatchers("/ws").permitAll(). 以确保这个端点没有被验证,并且但是有些东西坏了。我是 websockets 的新手,如果我搞砸了一些基本的东西,我很抱歉,我只是无法在网上找到合适的解决方案。

编辑: 我在 corsConfigurer 中添加了缺失的 .allowCredentials(true),现在控制台将请求标记为非失败请求,而是未授权请求(我想步骤更好。 ..)

实际上,由于我错误地使用了 httpSecurity configure(),因此授权无法正常工作。 我变了

 and().
 authorizeRequests().antMatchers("/ws").permitAll().

至:

 and().
 authorizeRequests().antMatchers("/ws/**").permitAll().

因此不会检查此端点的所有子项,从而消除 401 响应。