我有一个简单的 Web 应用程序,其中包含 Angular 前端和使用 Spring security JWT 身份验证(版本 3.0.5)的 Spring Boot API,部署在 Tomcat 10 中。Web 服务器和 APP/DB 服务器是分开的。出于隐私原因,我将审查该域名,并将其替换为 example.com。
我的 Cors 配置如下:
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Collections.singletonList("http://goods.example.com"));
configuration.setAllowedMethods(Arrays.asList("GET","POST", "PUT", "OPTIONS"));
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(Arrays.asList("Origin", "Access-Control-Allow-Origin", "Content-Type",
"Accept", "Jwt-Token", "Authorization", "X-Requested-With",
"Access-Control-Request-Method", "Access-Control-Request-Headers"));
configuration.setExposedHeaders(Arrays.asList("Origin", "Content-Type", "Accept", "Jwt-Token", "Authorization",
"Access-Control-Allow-Origin", "Access-Control-Allow-Origin", "Access-Control-Allow-Credentials", "Filename"));
configuration.setMaxAge(3600L);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
我的 Spring Security 配置如下:
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.cors()
.configurationSource(corsConfigurationSource())
.and()
.csrf()
.disable()
// .requiresChannel()
// .anyRequest()
// .requiresSecure()
// .and()
.authorizeHttpRequests( authCustomizer -> authCustomizer
.requestMatchers(HttpMethod.POST, "/api/v1/auth/authenticate").permitAll()
.requestMatchers(HttpMethod.GET, "/api/v1/test").permitAll()
)
.authorizeHttpRequests()
.anyRequest()
.authenticated()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authenticationProvider(authenticationProvider)
.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)
.headers()
.xssProtection()
.and()
.contentSecurityPolicy("default-src 'self' data: blob:;");
return httpSecurity.build();
}
如您所见,我现在正在 http 上运行该应用程序。
当我使用有效凭据调用身份验证端点时,它会显示以下标头:
HTTP/1.1 403
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: http://goods.example.com
Access-Control-Expose-Headers: Origin, Content-Type, Accept, Jwt-Token, Authorization, Access-Control-Allow-Origin, Access-Control-Allow-Origin, Access-Control-Allow-Credentials, Filename
Access-Control-Allow-Credentials: true
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/json
Transfer-Encoding: chunked
Date: Wed, 03 May 2023 09:11:19 GMT
Keep-Alive: timeout=20
Connection: keep-alive
现在问题来了。在我的日志中,我收到以下错误:
c.o.g.exception.DefaultExceptionHandler : java.lang.IllegalArgumentException: When allowCredentials is true, allowedOrigins cannot contain the special value "*" since that cannot be set on the "Access-Control-Allow-Origin" response header. To allow credentials to a set of origins, list them explicitly or consider using "allowedOriginPatterns" instead.
在我看来,我在我的 cors 配置中明确列出了允许的来源,但由于某种原因它不起作用......
我尝试过的:
@Order(Ordered.HIGHEST_PRECEDENCE)
这些是我在其他线程中找到的修复/我自己可以想到的修复。
需要说明的是,我在浏览器中没有收到错误,只是在 Java/Tomcat 中收到错误。可能是因为 Spring Boot 确实返回了正确的标头......
谢谢您的帮助!
我遇到了同样的问题,因为我没有正确配置 CORS。这是我的配置:
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.cors(c -> c.configurationSource(request -> {
CorsConfiguration cors = new CorsConfiguration();
cors.setAllowedOrigins(List.of("*"));
cors.setAllowedMethods(List.of("GET","POST", "PUT", "DELETE", "OPTIONS"));
cors.setAllowedHeaders(List.of("*"));
cors.setExposedHeaders(List.of(HttpHeaders.AUTHORIZATION, HttpHeaders.CONTENT_TYPE));
return cors;
}))
.authorizeHttpRequests()
...
这将允许为任何来源提供服务。也适用于任何方法。
我相信这可以帮助你解决这个问题。
在 corsConfigurationSource 中替换此
configuration.setAllowedOrigins(Collections.singletonList("http://goods.example.com"));
有了这个
configuration.addAllowedOriginPattern("*");