英文:
Spring Boot is ignoring my CORS configuration
问题
我有一个启用了CORS的REST API,但似乎Spring Boot忽略了我的CORS配置。以下是配置类:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
@Value(value = "${cors.allowed-origins}")
private List<String> allowedOrigins;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
return httpSecurity
.csrf().disable().cors().configurationSource(this.corsConfigurationSource()).and()
.authorizeHttpRequests().anyRequest().permitAll().and().build();
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(this.allowedOrigins);
configuration.setAllowedMethods(Arrays.asList(
HttpMethod.GET.name(), HttpMethod.POST.name(), HttpMethod.PUT.name(),
HttpMethod.DELETE.name(), HttpMethod.HEAD.name(), HttpMethod.OPTIONS.name()
));
configuration.setAllowedHeaders(Arrays.asList(
HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, HttpHeaders.CONTENT_TYPE, HttpHeaders.ACCEPT,
HttpHeaders.ORIGIN, HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS,
HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.AUTHORIZATION
));
configuration.setExposedHeaders(Arrays.asList(
HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD,
HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, HttpHeaders.ORIGIN, HttpHeaders.AUTHORIZATION
));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
这是Spring Boot应用程序类:
@SpringBootApplication(exclude = {UserDetailsServiceAutoConfiguration.class})
public class RaioXcapeBackend {
public static void main(String[] args) {
SpringApplication.run(RaioXcapeBackend.class, args);
}
}
我知道CORS配置没有生效,因为API允许来自任何来源的请求(例如:我从本地运行的前端发送了一个GET请求),但我的目标是只允许来自一个来源,即我部署的前端应用程序域。
可能发生了什么?我已经检查过${cors.allowed-origins}
,它是正确的。
更新1
以下是对API的GET请求的标头:
响应标头
Cache-Control:no-cache,no-store,max-age=0,must-revalidate
Connection:keep-alive
Content-Type:application/json
Date:Mon,19 Jun 2023 22:58:41 GMT
Expires:0
Keep-Alive:timeout=60
Pragma:no-cache
Transfer-Encoding:chunked
Vary:Access-Control-Request-Headers
Vary:Access-Control-Request-Method
Vary:Origin
X-Content-Type-Options:nosniff
X-Frame-Options:DENY
X-Xss-Protection:0
请求标头
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding:gzip,deflate,br
Accept-Language:en,pt;q=0.9
Cache-Control:no-cache
Connection:keep-alive
Dnt:1
Host:localhost:8080
Pragma:no-cache
Sec-Ch-Ua:Not.A/Brand;v=8,Chromium;v=114,Google Chrome;v=114
Sec-Ch-Ua-Mobile:?0
Sec-Ch-Ua-Platform:Windows
Sec-Fetch-Dest:document
Sec-Fetch-Mode:navigate
Sec-Fetch-Site:none
Sec-Fetch-User:?1
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0(Windows NT 10.0;Win64;x64)AppleWebKit/537.36(KHTML,like Gecko)Chrome/114.0.0.0 Safari/537.36
英文:
I have a REST API with CORS enabled, but it seems like Spring Boot is ignoring my CORS configuration. Here it is the configuration class:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
@Value(value = "${cors.allowed-origins}")
private List<String> allowedOrigins;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
return httpSecurity
.csrf().disable().cors().configurationSource(this.corsConfigurationSource()).and()
.authorizeHttpRequests().anyRequest().permitAll().and().build();
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(this.allowedOrigins);
configuration.setAllowedMethods(Arrays.asList(
HttpMethod.GET.name(), HttpMethod.POST.name(), HttpMethod.PUT.name(),
HttpMethod.DELETE.name(), HttpMethod.HEAD.name(), HttpMethod.OPTIONS.name()
));
configuration.setAllowedHeaders(Arrays.asList(
HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, HttpHeaders.CONTENT_TYPE, HttpHeaders.ACCEPT,
HttpHeaders.ORIGIN, HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS,
HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.AUTHORIZATION
));
configuration.setExposedHeaders(Arrays.asList(
HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD,
HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, HttpHeaders.ORIGIN, HttpHeaders.AUTHORIZATION
));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
And here it is the Spring Boot application class:
@SpringBootApplication(exclude = {UserDetailsServiceAutoConfiguration.class})
public class RaioXcapeBackend {
public static void main(String[] args) {
SpringApplication.run(RaioXcapeBackend.class, args);
}
}
I know that the CORS configuration is not being applied because the API is allowing requests from any origin (e.g.: I send a GET
request from my local running front-end), but my goal is to allow only from one origin, which is my deployed front-end application domain.
What could be happening? I've already checked the ${cors.allowed-origins}
, and it's correct.
UPDATE 1
Below are the headers of a GET
request to the API.
Response Headers
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Connection: keep-alive
Content-Type: application/json
Date: Mon, 19 Jun 2023 22:58:41 GMT
Expires: 0
Keep-Alive: timeout=60
Pragma: no-cache
Transfer-Encoding: chunked
Vary: Access-Control-Request-Headers
Vary: Access-Control-Request-Method
Vary: Origin
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-Xss-Protection: 0
Request Headers
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br
Accept-Language: en,pt;q=0.9
Cache-Control: no-cache
Connection: keep-alive
Dnt: 1
Host: localhost:8080
Pragma: no-cache
Sec-Ch-Ua: "Not.A/Brand";v="8", "Chromium";v="114", "Google Chrome";v="114"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
答案1
得分: 1
在控制器级别上添加 @EnableWebMvc
。
将URL值放入 application.properties
中。
以下是您可以用作配置的代码:
@Configuration
@PropertySource("classpath:application.properties")
public class SecurityConfiguration {
@Autowired
private Environment environment;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
return httpSecurity
.csrf().disable().cors().configurationSource(this.corsConfigurationSource()).and()
.authorizeHttpRequests().anyRequest().permitAll().and().build();
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(this.allowedOrigins);
configuration.setAllowedMethods(Arrays.asList(
HttpMethod.GET.name(), HttpMethod.POST.name(), HttpMethod.PUT.name(),
HttpMethod.DELETE.name(), HttpMethod.HEAD.name(), HttpMethod.OPTIONS.name()
));
configuration.setAllowedHeaders(Arrays.asList(
HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, HttpHeaders.CONTENT_TYPE, HttpHeaders.ACCEPT,
HttpHeaders.ORIGIN, HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS,
HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.AUTHORIZATION
));
configuration.setExposedHeaders(Arrays.asList(
HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD,
HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, HttpHeaders.ORIGIN, HttpHeaders.AUTHORIZATION
));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
@Override
public void addCorsMappings(CorsRegistry registry) {
String origins = environment.getProperty("url");
registry.addMapping("/v1/**")
.allowedMethods("PATCH", "GET", "POST", "OPTIONS", "PUT", "DELETE")
.allowedOrigins(origins.split(","))
.allowedHeaders("*").allowCredentials(true);
}
}
这是您提供的代码的翻译部分。
英文:
Place @EnableWebMvc
at Controller Level.
Place url value in application.properties
Below is the code that you can use as configuration.
@Configuration
@PropertySource("classpath:application.properties")
public class SecurityConfiguration {
@Autowired
private Environment environment;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
return httpSecurity
.csrf().disable().cors().configurationSource(this.corsConfigurationSource()).and()
.authorizeHttpRequests().anyRequest().permitAll().and().build();
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(this.allowedOrigins);
configuration.setAllowedMethods(Arrays.asList(
HttpMethod.GET.name(), HttpMethod.POST.name(), HttpMethod.PUT.name(),
HttpMethod.DELETE.name(), HttpMethod.HEAD.name(), HttpMethod.OPTIONS.name()
));
configuration.setAllowedHeaders(Arrays.asList(
HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, HttpHeaders.CONTENT_TYPE, HttpHeaders.ACCEPT,
HttpHeaders.ORIGIN, HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS,
HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.AUTHORIZATION
));
configuration.setExposedHeaders(Arrays.asList(
HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD,
HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, HttpHeaders.ORIGIN, HttpHeaders.AUTHORIZATION
));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
@Override
public void addCorsMappings(CorsRegistry registry) {
String origins = environment.getProperty("url");
registry.addMapping("/v1/**")
.allowedMethods("PATCH","GET", "POST", "OPTIONS","PUT", "DELETE")
.allowedOrigins(origins.split(","))
.allowedHeaders("*").allowCredentials(true);
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论