Spring 引导 - 'Access-Control-Allow-Origin' header 包含多个值,但预期只有一个
Spring Boot - The 'Access-Control-Allow-Origin' header contains multiple values but expect only one
我阅读了 Whosebug 上关于此主题的所有帖子,但没有找到答案,因为它们都与我的情况不同。
我的 spring 引导 API 使用 Spring 安全性并由 Angular 客户端访问。
Angular 客户端可以查询我的 API 添加“Access-Control-Allow-Origin
”作为“http://localhost:4200[=69=”的各种端点]" 使用 CorsConfiguration
setAllowedOrigins
方法。我得到了预期的回复,包括这个 header,所以一切都很好。
但是,其中一个端点 调用另一个 API。 API 也有自己的“Access-Control-Allow-Origin
”设置为“*”。
如果我的客户端查询此端点,我会收到以下错误:
"CORS 策略:'Access-Control-Allow-Origin' header 包含多个值 'http://localhost:4200, *',但只允许一个值。"
所以,第二个 API 添加了带有 * 的 header,然后我的 API 也添加了“http://localhost:4200”,最后我得到了 double Access-Control-Allow-Origin
header 中的条目,例如“http://localhost:4200, *”。
我想解决这个问题,但不知道如何解决。
我的 API 安全配置正在添加 CorsConfiguration,如下所示:
@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.authenticationProvider(...);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.
cors()
.and()
.csrf().disable()
.and()
.anyRequest()
.authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200"));
configuration.setAllowedMethods(Arrays.asList("*"));
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(Arrays.asList("*"));
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
我所有的控制器都带有注释:
@CrossOrigin(origins = "http://localhost:4200")
以上,我在API.
中调用setAllowedOrigins(Arrays.asList("http://localhost:4200"))
设置'Access-Control-Allow-Origin'header
我的 API 中的所有端点都按预期工作,除了一个调用另一个 API 的端点。 API 还将 'Access-Control-Allow-Origin' 设置为“”,然后返回到我的 API 中,结果是双值:“http://localhost:4200”和“" 在 'Access-Control-Allow-Origin'.
这是我的控制器和服务出现故障。如前所述,所有其他(不调用另一个 API)都工作正常。
下面是我的控制器,它调用我下面提供的服务。服务调用成功并且 returns 响应。但是,一旦将此响应发送到客户端,我就会收到上述错误。
@RestController
@RequestMapping("/wagen")
@CrossOrigin(origins = "http://localhost:4200")
public class WagenController {
public WagenController(WagenService service) {
wagenService = service;
}
@PostMapping
public ResponseEntity<WagenResponse> getWagen(@RequestBody WagenRequest wagenRequest, @RequestHeader HttpHeaders httpHeaders, HttpServletResponse response) {
ResponseEntity<WagenResponse> wagenResponse = wagenService.getWagen(wagenRequest, httpHeaders);
return wagenResponse;
}
}
这是我的服务。它使用 restTemplate 调用另一个 API。所有这一切都很好:
@Override
public ResponseEntity<WagenResponse> getWagen(WagenRequest wagenRequest, HttpHeaders httpHeaders) {
List<String> authHeader = httpHeaders.get("authorization");
HttpHeaders headers = new HttpHeaders();
// add BasicAuth for the other API before calling it in
// below restTemplate call
headers.add("Authorization", authHeader.get(0));
HttpEntity<WagenRequest> request = new HttpEntity<WagenRequest>(wagenRequest, headers);
ResponseEntity<WagenResponse> wagenResponse = restTemplate.postForEntity(uri, request, WagenResponse.class);
return wagenResponse;
}
如何解决这个问题,使我在 'Access-Control-Allow-Origin' 中没有第 2 个条目?或者其他方式?
我无法更改其他 API 发送给我的内容。
这是开发工具中网络选项卡的屏幕截图和控制台中显示的错误(这在 PostMan 中工作正常)。有趣的是,Firefox 开发工具显示 :
我是 Java Spring Boot 的新手,但这是我处理 CORS 的方式:
在 main() 下:
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:4200");
}
};
}
希望对您有所帮助!
问题在于您如何调用另一个 API,这是额外 CORS 的来源 header。
在此处转载的端点中,您调用 getWagen
并检索 ResponseEntity
作为响应:
@PostMapping
public ResponseEntity<WagenResponse> getWagen(@RequestBody WagenRequest wagenRequest, @RequestHeader HttpHeaders httpHeaders, HttpServletResponse response) {
ResponseEntity<WagenResponse> wagenResponse = wagenService.getWagen(wagenRequest, httpHeaders);
return wagenResponse;
}
问题出在您对 Wagen 的响应所做的操作 API。
A ResponseEntity
是来自其他 API 的 全部 响应——包括 header。如果您在该 return
语句上放置一个断点,您将能够探索 wagenResponse
object 并看到 header 包含 "*"
CORS header 作为 return 由其他人编辑 API。
通过 returning ResponseEntity
as-is,您将 returning 那些 API header .然后,您应用中的装饰器和注释会将您的 CORS headers 添加到 Wagen API 编辑的 return 顶部 .. .因此你的问题。
当您从 getWagen
方法返回 ResponseEntity<WagenResponse>
时,您需要挑选出您真正想要的位 -- body、状态、任何 non-CORS headers -- 然后生成一个 new ResponseEntity
to return 给调用者.
我阅读了 Whosebug 上关于此主题的所有帖子,但没有找到答案,因为它们都与我的情况不同。
我的 spring 引导 API 使用 Spring 安全性并由 Angular 客户端访问。
Angular 客户端可以查询我的 API 添加“Access-Control-Allow-Origin
”作为“http://localhost:4200[=69=”的各种端点]" 使用 CorsConfiguration
setAllowedOrigins
方法。我得到了预期的回复,包括这个 header,所以一切都很好。
但是,其中一个端点 调用另一个 API。 API 也有自己的“Access-Control-Allow-Origin
”设置为“*”。
如果我的客户端查询此端点,我会收到以下错误:
"CORS 策略:'Access-Control-Allow-Origin' header 包含多个值 'http://localhost:4200, *',但只允许一个值。"
所以,第二个 API 添加了带有 * 的 header,然后我的 API 也添加了“http://localhost:4200”,最后我得到了 double Access-Control-Allow-Origin
header 中的条目,例如“http://localhost:4200, *”。
我想解决这个问题,但不知道如何解决。
我的 API 安全配置正在添加 CorsConfiguration,如下所示:
@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.authenticationProvider(...);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.
cors()
.and()
.csrf().disable()
.and()
.anyRequest()
.authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200"));
configuration.setAllowedMethods(Arrays.asList("*"));
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(Arrays.asList("*"));
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
我所有的控制器都带有注释:
@CrossOrigin(origins = "http://localhost:4200")
以上,我在API.
中调用setAllowedOrigins(Arrays.asList("http://localhost:4200"))
设置'Access-Control-Allow-Origin'header
我的 API 中的所有端点都按预期工作,除了一个调用另一个 API 的端点。 API 还将 'Access-Control-Allow-Origin' 设置为“”,然后返回到我的 API 中,结果是双值:“http://localhost:4200”和“" 在 'Access-Control-Allow-Origin'.
这是我的控制器和服务出现故障。如前所述,所有其他(不调用另一个 API)都工作正常。
下面是我的控制器,它调用我下面提供的服务。服务调用成功并且 returns 响应。但是,一旦将此响应发送到客户端,我就会收到上述错误。
@RestController
@RequestMapping("/wagen")
@CrossOrigin(origins = "http://localhost:4200")
public class WagenController {
public WagenController(WagenService service) {
wagenService = service;
}
@PostMapping
public ResponseEntity<WagenResponse> getWagen(@RequestBody WagenRequest wagenRequest, @RequestHeader HttpHeaders httpHeaders, HttpServletResponse response) {
ResponseEntity<WagenResponse> wagenResponse = wagenService.getWagen(wagenRequest, httpHeaders);
return wagenResponse;
}
}
这是我的服务。它使用 restTemplate 调用另一个 API。所有这一切都很好:
@Override
public ResponseEntity<WagenResponse> getWagen(WagenRequest wagenRequest, HttpHeaders httpHeaders) {
List<String> authHeader = httpHeaders.get("authorization");
HttpHeaders headers = new HttpHeaders();
// add BasicAuth for the other API before calling it in
// below restTemplate call
headers.add("Authorization", authHeader.get(0));
HttpEntity<WagenRequest> request = new HttpEntity<WagenRequest>(wagenRequest, headers);
ResponseEntity<WagenResponse> wagenResponse = restTemplate.postForEntity(uri, request, WagenResponse.class);
return wagenResponse;
}
如何解决这个问题,使我在 'Access-Control-Allow-Origin' 中没有第 2 个条目?或者其他方式?
我无法更改其他 API 发送给我的内容。
这是开发工具中网络选项卡的屏幕截图和控制台中显示的错误(这在 PostMan 中工作正常)。有趣的是,Firefox 开发工具显示 :
我是 Java Spring Boot 的新手,但这是我处理 CORS 的方式: 在 main() 下:
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:4200");
}
};
}
希望对您有所帮助!
问题在于您如何调用另一个 API,这是额外 CORS 的来源 header。
在此处转载的端点中,您调用 getWagen
并检索 ResponseEntity
作为响应:
@PostMapping
public ResponseEntity<WagenResponse> getWagen(@RequestBody WagenRequest wagenRequest, @RequestHeader HttpHeaders httpHeaders, HttpServletResponse response) {
ResponseEntity<WagenResponse> wagenResponse = wagenService.getWagen(wagenRequest, httpHeaders);
return wagenResponse;
}
问题出在您对 Wagen 的响应所做的操作 API。
A ResponseEntity
是来自其他 API 的 全部 响应——包括 header。如果您在该 return
语句上放置一个断点,您将能够探索 wagenResponse
object 并看到 header 包含 "*"
CORS header 作为 return 由其他人编辑 API。
通过 returning ResponseEntity
as-is,您将 returning 那些 API header .然后,您应用中的装饰器和注释会将您的 CORS headers 添加到 Wagen API 编辑的 return 顶部 .. .因此你的问题。
当您从 getWagen
方法返回 ResponseEntity<WagenResponse>
时,您需要挑选出您真正想要的位 -- body、状态、任何 non-CORS headers -- 然后生成一个 new ResponseEntity
to return 给调用者.