Я занимаюсь разработкой приложения для Ionic на основе бэкэнда Spring.
Я реализовал Spring Security с аутентификацией JWT. В моем приложении будет чат, где пользователи могут общаться друг с другом в приватном или публичном чате. Итак, я внедряю систему WebSocket, чтобы получать все обновления в режиме реального времени.
Это моя конфигурация безопасности:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;
@Autowired
private UserDetailsService userDetailsService;
private AuthenticationManager authenticationManager;
@Autowired
public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder
.userDetailsService(this.userDetailsService)
.passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public JwtAuthenticationTokenFilter authenticationTokenFilterBean() throws Exception {
return new JwtAuthenticationTokenFilter();
}
// configurazione Cors per poter consumare le api restful con richieste ajax
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.addAllowedOrigin("*");
configuration.setAllowedMethods(Arrays.asList("POST, PUT, GET, OPTIONS, DELETE"));
configuration.addAllowedHeader("*");
configuration.addAllowedMethod("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.csrf().disable()
.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class)
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().cors().and()
.authorizeRequests()
.antMatchers(
HttpMethod.GET,
"/",
"/*.html",
"/favicon.ico",
"/**/*.html",
"/**/*.css",
"/**/*.js",
"/image/**").permitAll()
.antMatchers("/socket/**").permitAll()
.antMatchers("/public/**").permitAll().and()
.authorizeRequests().anyRequest().authenticated().and();
httpSecurity.headers().cacheControl();
}
@Bean
public AuthenticationManager customAuthenticationManager() throws Exception {
return authenticationManager();
}
}
Это моя конфигурация WebSocket:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration extends AbstractWebSocketMessageBrokerConfigurer{
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/socket")
.setAllowedOrigins("*")
.withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/chat")
.enableSimpleBroker("/subscribe");
}
}
В этом состоянии я сейчас сталкиваюсь с этой ошибкой:
Доступ к XMLHttpRequest по адресу
'http://localhost:8080/SpringApp/socket/info?t=1547732425329' от
origin 'http://localhost:8100' заблокирован политикой CORS:
значение заголовка «Access-Control-Allow-Origin» в ответе должно
не должен быть подстановочным знаком '*', когда режим учетных данных запроса
'включают'. Режим учетных данных запросов, инициированных
XMLHttpRequest управляется атрибутом withCredentials.
Каждый вызов работает (я полностью авторизован с помощью jwt), но WebSocket не может работать.
Итак, я попытался просто удалить .cors () в методе configure в моем классе конфигурации безопасности. Это привело меня к противоположной проблеме:
ошибка в хроме
Действительно, теперь WebSocket работает отлично, вместо этого каждый вызов API дает мне 401.
Как правильно решить эту проблему?
Спасибо