【问题标题】:Springboot - websocket unauthorized 401 with JWT authenticationSpringboot - 带有 JWT 身份验证的 websocket 未经授权的 401
【发布时间】:2021-02-16 07:23:27
【问题描述】:

在我的项目中,我通过 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 工作所需的东西,允许标头和来源,添加 authorizeRequests().antMatchers("/ws").permitAll(). 以确保此端点未经过验证,但有些东西会中断。我是 websockets 的新手,所以如果我搞砸了一些基本的东西,我很抱歉,我只是在网上找不到合适的解决方案。

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

【问题讨论】:

  • 看了他的申请后,我可以告诉你,你不应该关注它。它正在教导不良做法。实施任何类型的自定义安全性都是不好的做法,可能会意外引入安全问题。他写了一个 justom JWT 令牌过滤器,这是完全没有必要的,因为在 spring security docs.spring.io/spring-security/site/docs/5.4.1/reference/html5/… 中已经有一个内置的 JWT-filter 我强烈建议你从官方文档中学习 spring security。

标签: java spring-boot spring-security websocket spring-websocket


【解决方案1】:

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

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

到:

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

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

【讨论】:

    猜你喜欢
    • 2021-07-17
    • 2023-03-21
    • 2018-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-09
    • 2016-04-15
    相关资源
    最近更新 更多