简体   繁体   中英

Springboot - websocket unauthorized 401 with JWT authentication

In my project I authenticate logged user by JWT token. I am also creating web socket for chat module, but I cant establish connection with the backend (my front end is fine, I can connect to an example i've found here . In the authors code, the chat and auth are separate springboot projects, while I would like to keep it in one place. I have configured 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);
    }
}

My websocket config file:


@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;
    }
}

Also I have CORS configured here:

@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("*");
            }
        };
    }
}

As you can see, I think I took care of needed stuff for the cors to work, headers and origins are allowed, added authorizeRequests().antMatchers("/ws").permitAll(). to make sure this endpoint is not validated, and yet something breaks. I'm new to websockets, so I'm sorry if I messed up something elementary, I just cant find fitting solution online.

EDIT: I have aded missing .allowCredentials(true) in corsConfigurer, now console marks the request not as a failed one, but as an unauthorized (step better I suppose...)

更新

Actually, authorization was not working due to the fact that i used incorrectly httpSecurity configure(). I've changed

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

to:

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

So all children of this endpoint would be not checked, thus eliminating the 401 response.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM