我閱讀了有關此主題的 StackOverflow 上的所有帖子,但沒有找到答案,因為它們都與我的不同場景有關。
我的 Spring Boot API 使用 Spring Security 并由 Angular 客戶端訪問。
Angular 客戶端可以使用方法查詢我的 API 添加“ Access-Control-Allow-Origin”作為“ http://localhost:4200 ”的各種端點CorsConfiguration setAllowedOrigins。我得到了預期的回應,包括這個標題,所以一切都很好。
但是,其中一個端點呼叫另一個 API。該 API 也有自己的“ Access-Control-Allow-Origin”設定為“*”。
如果我的客戶查詢此端點,我會收到以下錯誤:
" CORS 策略:'Access-Control-Allow-Origin' 標頭包含多個值 'http://localhost:4200, *',但只允許一個值。 "
因此,第二個 API 在其中添加了帶有 * 的標頭,然后我的 API 還添加了“http://localhost:4200”,我最終在Access-Control-Allow-Origin標頭中輸入了雙重條目,例如“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")
在上面,我呼叫setAllowedOrigins(Arrays.asList("http://localhost:4200"))在我的 API 中設定“Access-Control-Allow-Origin”標頭。
我的 API 中的所有端點都按預期作業,除了一個呼叫另一個 API 的端點。該 API 還將“Access-Control-Allow-Origin”設定為“ ”,然后回傳到我的 API 中,從而產生雙值:“ Access-Control-Allow-Origin”中的“http://localhost:4200”和“” '。
這是我失敗的控制器和服務。如前所述,所有其他(不呼叫另一個 API)都作業正常。
下面是我的控制器,它呼叫下面提供的我的服務。服務呼叫成功并回傳回應。但是,一旦將此回應發送給客戶端,我就會收到上述錯誤。
@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”中沒有第二個條目?還是其他方式?
我沒有辦法更改其他 API 發送給我的內容。
這是開發工具中網路選項卡的螢屏截圖和控制臺中顯示的錯誤(這在 PostMan 中運行良好)。有趣的是,Firefox 開發工具顯示:


uj5u.com熱心網友回復:
問題在于您如何呼叫作為額外 CORS 標頭來源的其他 API。
在此處復制的端點中,您呼叫getWagen并檢索 aResponseEntity作為回應:
@PostMapping
public ResponseEntity<WagenResponse> getWagen(@RequestBody WagenRequest wagenRequest, @RequestHeader HttpHeaders httpHeaders, HttpServletResponse response) {
ResponseEntity<WagenResponse> wagenResponse = wagenService.getWagen(wagenRequest, httpHeaders);
return wagenResponse;
}
問題在于您正在處理來自 Wagen API 的回應。
AResponseEntity是來自其他 API 的整個回應——包括標頭。如果您在該陳述句上放置斷點return,您將能夠探索該wagenResponse物件并看到標頭包含"*"其他 API 回傳的 CORS 標頭。
通過按ResponseEntity原樣回傳,您也將回傳這些 API 標頭。然后,您在應用程式中擁有的裝飾器和注釋會將您的 CORS 標頭添加到 Wagen API 回傳的標頭之上......因此您的問題。
當您ResponseEntity<WagenResponse>從getWagen方法中回傳時,您需要挑選出您真正想要的位——主體、狀態、任何非 CORS 標頭——然后生成一個新 ResponseEntity的以回傳給呼叫者。
uj5u.com熱心網友回復:
我對 Java Spring Boot 很陌生,但這是我處理 CORS 的方式: 在 main() 下:
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:4200");
}
};
}
我希望它可以幫助你!
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/467703.html
