CORS の設定

セキュリティ上の理由から、ブラウザーは現在のオリジンの外部にあるリソースへの AJAX 呼び出しを禁止しています。ブラウザーによって発行されたクライアント側の HTTP リクエストを処理するときは、特定の HTTP リソースにアクセスできるようにする必要があります。

Spring Data REST は、2.6 の時点で、クロスオリジンリソースシェアリング [Mozilla] (CORS) から Spring の CORS サポートをサポートしています。

リポジトリインターフェースの CORS 設定

リポジトリインターフェースに @CrossOrigin アノテーションを追加して、リポジトリ全体で CORS を有効にすることができます。デフォルトでは、@CrossOrigin はすべてのオリジンと HTTP メソッドを許可します。次の例は、クロスオリジンリポジトリインターフェースの定義を示しています。

@CrossOrigin
interface PersonRepository extends CrudRepository<Person, Long> {}

前の例では、PersonRepository 全体で CORS サポートが有効になっています。次の例に示すように、@CrossOrigin は CORS サポートを設定するための属性を提供します。

@CrossOrigin(origins = "http://domain2.example",
  methods = { RequestMethod.GET, RequestMethod.POST, RequestMethod.DELETE },
  maxAge = 3600)
interface PersonRepository extends CrudRepository<Person, Long> {}

前の例では、GETPOSTDELETE メソッドに制限され、最大経過時間が 3600 秒の 1 つのオリジンを提供することにより、PersonRepository 全体の CORS サポートを有効にします。

リポジトリ REST コントローラーメソッド CORS 構成

Spring Data REST は、次の例に示すように、リポジトリの基本パスを共有するカスタム REST コントローラーで Spring Web MVC のコントローラーメソッド構成を完全にサポートします。

@RepositoryRestController
public class PersonController {

  @CrossOrigin(maxAge = 3600)
  @RequestMapping(path = "/people/xml/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_XML_VALUE)
  public Person retrieve(@PathVariable Long id) {
    // …
  }
}
@RepositoryRestController アノテーションが付けられたコントローラーは、関連するリポジトリから @CrossOrigin 構成を継承します。

グローバル CORS 構成

きめの細かいアノテーションベースの構成に加えて、おそらくグローバルな CORS 構成も定義する必要があります。これは Spring Web MVC の CORS 構成に似ていますが、Spring Data REST 内で宣言して、きめの細かい @CrossOrigin 構成と組み合わせることができます。デフォルトでは、すべてのオリジンと GETHEADPOST メソッドが許可されます。

既存の Spring Web MVC CORS 構成は、Spring Data REST には適用されません。

次の例では、許可されたオリジンを設定し、PUT および DELETE HTTP メソッドを追加し、いくつかのヘッダーを追加して公開し、最大経過時間を 1 時間に設定します。

@Component
public class SpringDataRestCustomization implements RepositoryRestConfigurer {

  @Override
  public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config, CorsRegistry cors) {

    cors.addMapping("/person/**")
      .allowedOrigins("http://domain2.example")
      .allowedMethods("PUT", "DELETE")
      .allowedHeaders("header1", "header2", "header3")
      .exposedHeaders("header1", "header2")
      .allowCredentials(false).maxAge(3600);
  }
}