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レポジトリには、このトピックに関するほとんどのエッジケースを分析するテストケースとともに、多くの例があります。