我正在基于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");
}
}
在这种情况下,我目前遇到此错误:
在以下位置访问XMLHttpRequest 来自的“ http://localhost:8080/SpringApp/socket/info?t=1547732425329” 原产地“ http://localhost:8100”已被CORS政策禁止: 响应中“ Access-Control-Allow-Origin”标头的值必须 当请求的凭据模式为时,不是通配符“ *” '包括'。发起的请求的凭据模式 XMLHttpRequest由withCredentials属性控制。
每个调用都可以正常工作(我已获得jwt的完全授权),但WebSocket无法正常工作。
因此,我尝试在安全配置类中的configure方法中删除.cors()。这导致我遇到了相反的问题:
实际上,现在WebSocket可以完美运行,而是每个api调用都能给我401。
解决此问题的正确方法是什么? 谢谢
答案 0 :(得分:1)
对于任何人复制和粘贴问题中的代码:以下行不正确:
configuration.setAllowedMethods(Arrays.asList("POST, PUT, GET, OPTIONS, DELETE"));
应该是:
configuration.setAllowedMethods(Arrays.asList("POST", "PUT", "GET", "OPTIONS", "DELETE"));
答案 1 :(得分:0)
是的,当我在一个项目中处理相关问题时,遇到了同样的错误。解决方案是我必须将allowed-origin标头值设置为应用程序的URL。如果您发送凭据,则不允许使用通配符(*)。