Spring SecurityのCORS設定入門!REST APIを安全に公開するための手順とポイント
Spring Bootを使ったWebアプリケーション開発を、 環境構築から実践まで一通り学びたい方には、 定評のある入門書が参考になります。
Spring Boot 3 プログラミング入門をAmazonで見る※ Amazon広告リンク
生徒
「REST APIをJavaとSpringで作ったんですけど、フロントエンドからアクセスするとエラーになります…」
先生
「それはCORS、つまりクロスオリジンリクエスト制限が原因ですね。Spring SecurityのCORS設定を正しく行えば解決できますよ。」
生徒
「CORSって何ですか?設定の方法も知りたいです!」
先生
「それでは、CORSの基本からSpring Securityでの設定方法まで、わかりやすく解説していきましょう。」
1. CORSとは?なぜ必要なのか?
CORS(コース)とは「Cross-Origin Resource Sharing」の略で、異なるドメイン間でのリクエストを制御する仕組みです。例えば、フロントエンドがhttp://localhost:3000で、バックエンドAPIがhttp://localhost:8080の場合、ブラウザはセキュリティ上の理由からそのままではアクセスを許可しません。
これを許可するには、サーバー側で「CORSポリシー」を明示的に設定する必要があります。Spring BootやSpring Securityでは、適切な設定を加えることで、安全にクロスオリジン通信を許可できます。
2. Spring Bootでの基本的なCORS設定
もっとも簡単な方法は、@CrossOriginアノテーションを使って特定のControllerまたはメソッドに対してCORSを許可する方法です。
@RestController
@RequestMapping("/api")
public class ApiController {
@CrossOrigin(origins = "http://localhost:3000")
@GetMapping("/hello")
public String hello() {
return "こんにちは、CORS!";
}
}
origins属性で許可するドメインを指定します。複数のオリジンを許可することも可能です。
3. グローバルにCORS設定を行う方法
アノテーションではなく、すべてのAPIに対して一括でCORS設定を行いたい場合は、WebMvcConfigurerを使います。
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:3000")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowCredentials(true);
}
}
この方法では、すべてのパス/**に対してCORSを許可し、使用可能なHTTPメソッドや認証情報の送信も指定できます。
Spring FrameworkやThymeleafを使った Webアプリ開発の全体像をやさしく理解したい人には、 この入門書が定番です。
Spring Framework超入門をAmazonで見る※ Amazon広告リンク
4. Spring SecurityとCORSの連携に注意
Spring Securityを導入している場合、WebMvcConfigurerだけではCORSが機能しないことがあります。その場合、SecurityFilterChain内でもCORSを有効にする必要があります。
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.cors(Customizer.withDefaults()) // CORSを有効にする
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.anyRequest().permitAll()
);
return http.build();
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(List.of("http://localhost:3000"));
config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE"));
config.setAllowCredentials(true);
config.setAllowedHeaders(List.of("*"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
}
Spring Securityのフィルタ内で.cors()を有効にし、CORS設定のBeanを用意することで、REST APIへのクロスオリジンアクセスが安全に実現できます。
5. CORSのプリフライトリクエストとは?
ブラウザは安全性を確保するために、特定の条件に該当するリクエストを「プリフライトリクエスト」としてOPTIONSメソッドで送信します。これは事前確認の意味を持ち、本リクエストの前にサーバーの許可を得るために行われます。
たとえば、JSONデータのPOST送信やカスタムヘッダーを含む場合などはプリフライト対象になります。Spring BootではCORS設定でOPTIONSメソッドも許可しておく必要があります。
6. CORS設定でよくあるエラーとその解決方法
実務では以下のようなCORS関連エラーが頻繁に発生します。
- Access-Control-Allow-Originが無い:指定のオリジンが正しくない、または設定漏れが原因です。
- プリフライトに失敗:OPTIONSメソッドが拒否されている、または
allowedMethodsに設定されていないことが多いです。 - 認証情報が送れない:
allowCredentials(true)が設定されていない、またはallowedOriginsにワイルドカード*を使ってしまっている場合です。
開発時はフロントエンドのエラーコンソールを確認し、CORSヘッダーが正しく返っているかをチェックすることが重要です。
7. CORSとセキュリティのベストプラクティス
クロスオリジン通信を許可するCORS設定は便利ですが、広く許可しすぎるとセキュリティリスクとなります。以下の点に注意しましょう。
- 必要なドメインだけを
allowedOriginsに指定する - 本番環境では
*の使用を避ける - REST APIが公開される用途を明確にし、不要なメソッドは許可しない
- Spring Securityと一貫性のある設定を行う
安全なAPI公開には、CORSの深い理解と、状況に応じた柔軟な設定が欠かせません。
まとめ
Spring SecurityとCORS設定の全体像を振り返る
この記事では、Spring Securityを利用したREST API開発において非常に重要となるCORS設定について、基礎から実践まで段階的に学んできました。CORSはクロスオリジン通信を安全に制御するための仕組みであり、フロントエンドとバックエンドを分離したモダンなWebアプリケーション開発では避けて通れないテーマです。特にSpring BootとSpring Securityを組み合わせた構成では、単純な設定だけでは意図した通りに動作しないケースも多く、正しい理解が求められます。
まずCORSとは何か、なぜブラウザが異なるオリジンからのアクセスを制限するのかを理解することで、エラーの正体が明確になりました。フロントエンドからAPIを呼び出した際に発生するエラーの多くは、アプリケーションの不具合ではなく、ブラウザがセキュリティのために通信をブロックしていることが原因です。この仕組みを知ることで、不要に悩む時間を減らすことができます。
用途に応じたCORS設定方法の使い分け
次に、Spring Bootで利用できる複数のCORS設定方法について確認しました。@CrossOriginアノテーションを使った方法は、Controller単位やメソッド単位で柔軟に設定できるため、小規模なAPIや検証用途に向いています。一方で、アプリケーション全体に共通のルールを適用したい場合は、WebMvcConfigurerを使ったグローバル設定が有効です。
しかし、Spring Securityを導入している場合は注意が必要です。WebMvcConfigurerだけでCORS設定を行っても、セキュリティフィルタの段階でリクエストが拒否されてしまうことがあります。そのため、SecurityFilterChainでCORSを有効にし、CorsConfigurationSourceを定義することが重要になります。この連携を正しく行うことで、REST APIへのクロスオリジンアクセスを安全に許可できます。
設定例を通して理解を深める
以下は、今回学んだ内容を整理したCORS設定のサンプルプログラムです。記事内で紹介したクラス構成や書き方と同じ形式を使い、実務でもそのまま応用しやすい形にしています。
@Configuration
@EnableWebSecurity
public class ApiSecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.cors(Customizer.withDefaults())
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.anyRequest().permitAll()
);
return http.build();
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(List.of("http://localhost:3000"));
configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
configuration.setAllowedHeaders(List.of("*"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
このようにCORS設定を明示的に行うことで、フロントエンドとバックエンドが異なるドメインで動作していても、Spring Securityの制御下で安全に通信できるようになります。特にOPTIONSメソッドの許可や、allowCredentialsの扱いは実務でつまずきやすいポイントのため、設定内容を一つ一つ理解しながら進めることが大切です。
実務で役立つ考え方と注意点
CORS設定は「とりあえず動かす」ために広く許可してしまいがちですが、それはセキュリティリスクにつながります。必要なオリジンだけを許可し、不要なHTTPメソッドは制限することで、安全性と利便性のバランスを保つことができます。また、開発環境と本番環境で設定を分けることも重要です。
エラーが発生した場合は、ブラウザの開発者ツールでレスポンスヘッダーを確認し、Access-Control-Allow-OriginやAccess-Control-Allow-Methodsが正しく返っているかをチェックしましょう。原因を一つずつ切り分けることで、CORSエラーへの対応力が確実に身についていきます。
生徒
「最初はエラーばかりで難しそうだと思っていましたが、CORSの仕組みを知ったら原因がはっきりしました。Spring Securityと一緒に設定する必要があるんですね。」
先生
「その通りです。CORSはブラウザ側の仕組みなので、サーバーがどう応答するかを理解することが大切ですね。Spring Securityを使う場合は、セキュリティフィルタとの関係を意識しましょう。」
生徒
「allowedOriginsやallowedMethodsをきちんと指定することで、安全にREST APIを公開できることが分かりました。実務でもそのまま使えそうです。」
先生
「理解できていますね。CORS設定は一度身につけると、フロントエンドとバックエンドを分けた開発がとても楽になります。今回の内容を土台に、さらに実践経験を積んでいきましょう。」