春のCORS
1. 概要
In any modern browser, Cross-Origin Resource Sharing (CORS) is a relevant specification with the emergence of HTML5 and JS clients that consume data via REST APIs.
多くの場合、JSにサービスを提供するホスト(例: example.com)は、データを提供するホストとは異なります(例: api.example.com)。 このような場合、CORSはクロスドメイン通信を可能にします。
SpringはCORSにファーストクラスのsupportを提供し、SpringまたはSpringBootWebアプリケーションで簡単かつ強力に構成する方法を提供します。
2. コントローラ方式のCORS設定
CORSの有効化は簡単です—アノテーション@CrossOriginを追加するだけです。
これは、いくつかの異なる方法で実装できます。
2.1. @RequestMappingの@CrossOrigin–アノテーション付きハンドラーメソッド
@RestController
@RequestMapping("/account")
public class AccountController {
@CrossOrigin
@RequestMapping(method = RequestMethod.GET, path = "/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
上記の例では、 retrieve()メソッドに対してのみCORSを有効にしました。 @CrossOrigin アノテーションの構成を設定していないことがわかります。そのため、デフォルトが使用されます。
- すべての起源が許可されます。
- 許可されるHTTPメソッドは、 @RequestMapping アノテーション(この例ではGET)で指定されたものです。
- プリフライト応答がキャッシュされる時間( maxAge )は30分です。
2.2. コントローラの@CrossOrigin
@CrossOrigin(origins = "http://example.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {
@RequestMapping(method = RequestMethod.GET, path = "/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
今回は、クラスレベルで@CrossOriginを追加しました。 したがって、 retrieve()メソッドと remove()メソッドの両方で有効になっています。 アノテーション属性の1つの値を指定することで構成をカスタマイズできます: origins 、 methods 、 allowedHeaders 、 exposedHeaders 、[X182X ] allowCredentials 、またはmaxAge。
2.3. @CrossOriginコントローラーおよびハンドラーメソッド
@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {
@CrossOrigin("http://example.com")
@RequestMapping(method = RequestMethod.GET, "/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
Springは、両方のアノテーションの属性を組み合わせて、マージされたCORS構成を作成します。
ここで、両方のメソッドの maxAge は3,600秒で、メソッド remove()はすべてのオリジンを許可し、メソッド retrieve()はオリジンのみを許可しますhttp://example.comから。
3. グローバルCORS構成
As an alternative to the fine-grained annotation-based configuration, Spring lets us define a global CORS configuration out of our controllers. This is similar to using a Filter-based solution but can be declared within Spring MVC and combined with a fine-grained @CrossOrigin configuration.
By default, all origins and GET, HEAD, and POST methods are allowed.
3.1. JavaConfig
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
上記の例では、アプリケーション内の任意のオリジンから任意のエンドポイントへのCORSリクエストを有効にします。
これをもう少しロックダウンするために、registerry.addMappingメソッドはCorsRegistrationオブジェクトを返します。これは、追加の構成に使用できます。 許可されたオリジンの配列を指定できるallowedOriginsメソッドもあります。 これは、実行時に外部ソースからこの配列をロードする必要がある場合に役立ちます。
さらに、設定に使用できる allowedMethods 、 allowedHeaders 、 exposedHeaders 、 maxAge 、allowCredentialsもあります。応答ヘッダーとカスタマイズオプション。
3.2. XML名前空間
この最小限のXML構成により、JavaConfigと同じデフォルトプロパティを使用して /**パスパターンでCORSが有効になります。
<mvc:cors>
<mvc:mapping path="/**" />
</mvc:cors>
カスタマイズされたプロパティを使用して、いくつかのCORSマッピングを宣言することもできます。
<mvc:cors>
<mvc:mapping path="/api/**"
allowed-origins="http://domain1.com, http://domain2.com"
allowed-methods="GET, PUT"
allowed-headers="header1, header2, header3"
exposed-headers="header1, header2" allow-credentials="false"
max-age="123" />
<mvc:mapping path="/resources/**"
allowed-origins="http://domain1.com" />
</mvc:cors>
4. SpringSecurityを使用したCORS
プロジェクトでSpringSecurityを使用する場合は、CORSで適切に機能するように追加の手順を実行する必要があります。 これは、CORSを最初に処理する必要があるためです。 それ以外の場合、SpringSecurityはSpringMVCに到達する前にリクエストを拒否します。
幸い、SpringSecurityはすぐに使用できるソリューションを提供します。
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.cors().and()...
}
}
この記事で詳しく説明しています。
5. 使い方
CORSリクエストは、登録されているさまざまなHandlerMappingsに自動的にディスパッチされます。 CORSプリフライトリクエストを処理し、 CorsProcessor 実装(デフォルトでは DefaultCorsProcessor )を使用してCORSの単純なリクエストと実際のリクエストをインターセプトし、関連するCORSレスポンスヘッダー( Access-Control-など)を追加します。 Allow-Origin )。
CorsConfiguration allows us to specify how the CORS requests should be processed, including allowed origins, headers, and methods, among others. さまざまな方法で提供できます。
- AbstractHandlerMapping#setCorsConfiguration()を使用すると、 / api /**などのパスパターンにマップされた複数のCorsConfigurationを含むMapを指定できます。 。
- サブクラスは、 AbstractHandlerMapping#getCorsConfiguration(Object、HttpServletRequest)メソッドをオーバーライドすることにより、独自のCorsConfigurationを提供できます。
- ハンドラーは、 CorsConfigurationSource インターフェースを実装して( ResourceHttpRequestHandler が現在行っているように)、各要求にCorsConfigurationを提供できます。
6. 結論
この記事では、SpringがアプリケーションでCORSを有効にするためのサポートをどのように提供するかを示しました。
コントローラの設定から始めました。 CORSを1つの特定のメソッドまたはコントローラー全体に対して有効にするには、アノテーション@CrossOriginを追加するだけでよいことがわかりました。
また、コントローラーの外部でCORS構成を制御するために、JavaConfigまたはXMLのいずれかを使用して構成ファイルでこれをスムーズに実行できることも学びました。
例の完全なソースコードは、GitHubでから入手できます。