spring - Spring Security 和 Websocket 的 CORS 问题
问题描述
我正在开发一个基于 Spring 后端的 Ionic 应用程序。我使用 JWT 身份验证实现了 Spring Security。我的应用程序将有一个聊天室,用户可以在其中私下或公开聊天。所以,我正在实现一个 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");
}
}
在这种情况下,我目前面临这个错误:
从源“ http://localhost:8100 ”访问“ http://localhost:8080/SpringApp/socket/info?t=1547732425329 ”的 XMLHttpRequest已被 CORS 策略阻止:“Access-Control-”的值当请求的凭据模式为“包含”时,响应中的 Allow-Origin 标头不得为通配符“*”。XMLHttpRequest 发起的请求的凭证模式由 withCredentials 属性控制。
每个调用都在工作(我完全获得了 jwt 的授权),但 WebSocket 无法工作。
因此,我尝试在我的安全配置类中简单地删除 configure 方法中的 .cors() 。这导致我遇到一个相反的问题:
确实,现在 WebSocket 可以完美运行,而不是每个 api 调用都给我 401。
解决此问题的正确方法是什么?谢谢
解决方案
对于复制和粘贴问题中的代码的任何人:以下行不正确:
configuration.setAllowedMethods(Arrays.asList("POST, PUT, GET, OPTIONS, DELETE"));
它应该是:
configuration.setAllowedMethods(Arrays.asList("POST", "PUT", "GET", "OPTIONS", "DELETE"));
推荐阅读
- typescript - TypeScript 中有没有一种方法可以在不丢失对象特异性的情况下使用接口作为保护?
- c++ - 如何从精明的图像中去除高频区域?
- html - 如何使具有响应式设计的嵌套表与 Gmail 兼容
- javascript - 更新状态反应
- python - 如何使用 Python 分析 docx 文件中的注释语句?
- html - 角垫形式场不会扩大
- javascript - html-docx-js 在创建 docx 文件时不能应用外部 css 类样式
- python - 为 Teradata DB 表格式化 Python 时间戳
- azure-sql-data-warehouse - ALTER TABLE SWITCH 语句失败。表 X 中的分区 1 定义的范围不是表 Y 中的分区 2 定义的范围的子集
- python - 向 Scrapy Spider 添加标题