SpringWebfluxとCORS
1. 概要
以前の投稿では、クロスオリジンリソースシェアリング(CORS)の仕様と、Spring内での使用方法について学びました。
このクイックチュートリアルでは、 Springの5WebFluxフレームワークを使用して同様のCORS構成をセットアップします。
まず、アノテーションベースのAPIでメカニズムを有効にする方法を見ていきます。
次に、プロジェクト全体でグローバル構成として、または特別なWebFilterを使用してそれを有効にする方法を分析します。
2. 注釈付き要素でのCORSの有効化
Springは@CrossOriginアノテーションを提供して、コントローラークラスやハンドラーメソッドでCORSリクエストを有効にします。
2.1. リクエストハンドラメソッドで@CrossOriginを使用する
このアノテーションをマップされたリクエストメソッドに追加しましょう。
@CrossOrigin
@PutMapping("/cors-enabled-endpoint")
public Mono<String> corsEnabledEndpoint() {
// ...
}
WebTestClient を使用します(セクション ‘4で説明したように)。 このエンドポイントから得られる応答を分析するためのこの投稿)のテスト:
ResponseSpec response = webTestClient.put()
.uri("/cors-enabled-endpoint")
.header("Origin", "http://any-origin.com")
.exchange();
response.expectHeader()
.valueEquals("Access-Control-Allow-Origin", "*");
さらに、プリフライトリクエストを試して、CORS設定が期待どおりに機能していることを確認できます。
ResponseSpec response = webTestClient.options()
.uri("/cors-enabled-endpoint")
.header("Origin", "http://any-origin.com")
.header("Access-Control-Request-Method", "PUT")
.exchange();
response.expectHeader()
.valueEquals("Access-Control-Allow-Origin", "*");
response.expectHeader()
.valueEquals("Access-Control-Allow-Methods", "PUT");
response.expectHeader()
.exists("Access-Control-Max-Age");
@CrossOrigin アノテーションには、次のデフォルト構成があります。
- すべてのオリジンを許可します(これは、応答ヘッダーの「*」値を説明します)
- すべてのヘッダーを許可します
- ハンドラーメソッドによってマップされたすべてのHTTPメソッドが許可されます
- クレデンシャルが有効になっていません
- ‘max-age’値は1800秒(30分)です
ただし、これらの値はいずれも、注釈のパラメーターを使用してオーバーライドできます。
2.2. コントローラで@CrossOriginを使用する
このアノテーションはクラスレベルでもサポートされており、そのすべてのメソッドに影響します。
クラスレベルの構成がすべてのメソッドに適していない場合は、両方の要素に注釈を付けて、目的の結果を得ることができます。
@CrossOrigin(value = { "http://allowed-origin.com" },
allowedHeaders = { "Baeldung-Allowed" },
maxAge = 900
)
@RestController
public class CorsOnClassController {
@PutMapping("/cors-enabled-endpoint")
public Mono<String> corsEnabledEndpoint() {
// ...
}
@CrossOrigin({ "http://another-allowed-origin.com" })
@PutMapping("/endpoint-with-extra-origin-allowed")
public Mono<String> corsEnabledWithExtraAllowedOrigin() {
// ...
}
// ...
}
3. グローバル構成でのCORSの有効化
WebFluxConfigurer実装のaddCorsMappings()メソッドをオーバーライドすることで、グローバルCORS構成を定義することもできます。
さらに、実装には、プレーンなSpringアプリケーションにSpring WebFlux構成をインポートするために、@EnableWebFluxアノテーションが必要です。 Spring Bootを使用している場合、自動構成をオーバーライドする場合にのみ、このアノテーションが必要になります。
@Configuration
@EnableWebFlux
public class CorsGlobalConfiguration implements WebFluxConfigurer {
@Override
public void addCorsMappings(CorsRegistry corsRegistry) {
corsRegistry.addMapping("/**")
.allowedOrigins("http://allowed-origin.com")
.allowedMethods("PUT")
.maxAge(3600);
}
}
その結果、その特定のパスパターンに対してクロスオリジンリクエスト処理を有効にしています。
デフォルトの設定は@CrossOriginの設定と似ていますが、 GET 、 HEAD 、およびPOSTメソッドのみが許可されています。
この構成をローカル構成と組み合わせることもできます。
- 複数値属性の場合、結果のCORS構成は、各仕様の追加になります
- 一方、単一値の場合は、ローカル値がグローバル値よりも優先されます。
ただし、このアプローチの使用は、機能的なエンドポイントには効果的ではありません。
4. WebFilterを使用したCORSの有効化
機能エンドポイントでCORSを有効にする最良の方法は、WebFilterを使用することです。
この投稿でを見たように、 WebFilter を使用して、エンドポイントの実装をそのままにしながら、要求と応答を変更できます。
Springには、クロスオリジン構成を簡単に処理できるように、組み込みのCorsWebFilterが用意されています。
@Bean
CorsWebFilter corsWebFilter() {
CorsConfiguration corsConfig = new CorsConfiguration();
corsConfig.setAllowedOrigins(Arrays.asList("http://allowed-origin.com"));
corsConfig.setMaxAge(8000L);
corsConfig.addAllowedMethod("PUT");
corsConfig.addAllowedHeader("Baeldung-Allowed");
UrlBasedCorsConfigurationSource source =
new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfig);
return new CorsWebFilter(source);
}
これはアノテーション付きハンドラーにも効果的ですが、よりきめ細かい@CrossOrigin構成と組み合わせることはできません。
CorsConfigurationにはデフォルト構成がないことに注意する必要があります。
したがって、関連するすべての属性を指定しない限り、CORSの実装はかなり制限されます。
デフォルト値を設定する簡単な方法は、オブジェクトで applyPermitDefaultValues()メソッドを使用することです。
5. 結論
結論として、webfluxベースのサービスでCORSを有効にする方法の非常に短い例で学びました。
さまざまなアプローチを見たので、今やらなければならないのは、どれが要件に最も適しているかを分析することだけです。
GitHubレポジトリには、このトピックに関するほとんどのエッジケースを分析するテストケースとともに、多くの例があります。