カテゴリ: Spring認証(Spring Security) 更新日: 2025/12/06

CORSプリフライトリクエストの処理を理解しよう!初心者向けにSpring SecurityとOPTIONSメソッドを解説

CORSプリフライトリクエストの処理
CORSプリフライトリクエストの処理

新人と先輩の会話形式で理解しよう

新人

「先輩、CORSって最近よく聞くんですが、セキュリティに関係してるんですか?」

先輩

「その通り。CORSは『クロスオリジンリソースシェアリング』の略で、異なるドメイン間でリソースをやり取りするときのセキュリティルールなんだ。」

新人

「なるほど…でも、なぜそんな制限が必要なんですか?」

先輩

「たとえば悪意あるサイトが、あなたのログイン済み情報を使って勝手にAPIを叩いたら大変でしょ?そうならないようにCORS設定があるんだ。」

新人

「じゃあ、プリフライトリクエストっていうのもCORSと関係あるんですね?」

先輩

「その通り。OPTIONSメソッドを使った通信がそれなんだ。詳しく説明しよう!」

1. CORSとは何か?セキュリティ対策としての意味

1. CORSとは何か?セキュリティ対策としての意味
1. CORSとは何か?セキュリティ対策としての意味

CORS(コース、Cross-Origin Resource Sharing)は、異なるオリジン間での通信を制限・制御する仕組みです。たとえば、https://example.comからhttps://api.example.jpのAPIにアクセスするとき、ブラウザはセキュリティ上の理由から制限をかけます。

これにより、悪意あるJavaScriptがユーザーの認証情報を使って勝手に別ドメインへアクセスすることを防止できます。CORS設定を明示的にサーバー側で行わないと、リクエストがブロックされてしまいます。

Spring Securityでは、セキュリティ機構が厳格に設定されており、CORS設定を無視するとAPIへのアクセスが拒否されることがあります。開発環境がpleiades + Gradleの場合でも、適切な@Configurationを用いたCORS設定が求められます。

たとえば、以下のようにCORS設定をJavaで記述できます。


@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
            .allowedOrigins("https://frontend.example.com")
            .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS");
    }
}

このようにして、Spring Security環境でもクロスオリジン通信を許可できます。

2. プリフライトリクエストとは?OPTIONSメソッドの役割

2. プリフライトリクエストとは?OPTIONSメソッドの役割
2. プリフライトリクエストとは?OPTIONSメソッドの役割

「プリフライトリクエスト」とは、CORSが有効な状況で行われる事前確認リクエストのことです。主にPUTDELETEなどの特殊なHTTPメソッドや、Content-Type: application/jsonなどの特殊ヘッダーを使用する際に発生します。

このとき、ブラウザはまずOPTIONSメソッドでリクエストを送信し、そのリクエストが安全に行えるかどうかを確認します。これが「プリフライトリクエスト」です。

Spring SecurityでこのOPTIONSメソッドを正しく処理しないと、プリフライトリクエストが失敗し、以降の通信がブロックされてしまいます。

たとえば、Spring Securityの設定で以下のように記述する必要があります。


@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .cors().and()
            .csrf().disable()
            .authorizeHttpRequests(auth -> auth
                .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                .anyRequest().authenticated()
            );
        return http.build();
    }
}

HttpMethod.OPTIONSを許可している点が、プリフライトリクエストを処理する上で非常に重要です。

この設定がなければ、プリフライトリクエストが403エラーで拒否され、本来のPOSTPUTリクエストも通らなくなります。

また、@Controllerを使った通常のSpringアプリケーションでも、OPTIONSメソッドへの対応はWebMvcConfigurerで設定することで実現可能です。


@Controller
public class TestController {

    @PostMapping("/api/test")
    @ResponseBody
    public String test() {
        return "OK";
    }
}

この@PostMappingが呼び出される前に、OPTIONSメソッドによるプリフライトリクエストが通過している必要があることを忘れないでください。

3. Springでプリフライトリクエストを処理する仕組み

3. Springでプリフライトリクエストを処理する仕組み
3. Springでプリフライトリクエストを処理する仕組み

Springでは、プリフライトリクエスト(OPTIONSメソッド)を自動的に処理できる仕組みが用意されています。Spring MVCやSpring Securityの設定を正しく行えば、CORSのプリフライト対応は比較的簡単に実現できます。

ポイントは、OPTIONSメソッドを認可の対象から除外し、適切にレスポンスを返せるようにすることです。前のセクションで紹介したように、requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()の設定が重要になります。

この設定を行うことで、ブラウザからのプリフライトリクエストをサーバー側で拒否せず、必要なCORSヘッダー付きのレスポンスを返せるようになります。

Spring SecurityではCORSフィルタが先に動くように制御されているため、CORS設定を行っていればOPTIONSメソッドを個別にコントローラでハンドリングする必要は基本的にありません。

ただし、Controller CORSの動作を確認する際には、フィルタの順番や設定漏れに注意する必要があります。CORSに関するエラーの多くは、プリフライトリクエストが正しく処理されていないことが原因です。

4. @CrossOriginでのプリフライト対応(実装例)

4. @CrossOriginでのプリフライト対応(実装例)
4. @CrossOriginでのプリフライト対応(実装例)

Springでは、特定のコントローラやメソッドに対して簡単にCORS設定を行うためのアノテーション@CrossOriginが用意されています。

このアノテーションを使うことで、プリフライトリクエストにも自動的に対応できるようになります。

以下は、@Controllerを使った実装例です。開発環境はpleiades + Gradleが前提です。


@Controller
@CrossOrigin(
    origins = "https://frontend.example.com",
    methods = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE, RequestMethod.OPTIONS}
)
public class ApiController {

    @PostMapping("/api/data")
    @ResponseBody
    public String postData() {
        return "データを受け取りました";
    }
}

@CrossOriginをクラスレベルに指定することで、そのクラス内のすべてのエンドポイントに対してCORS設定が適用されます。

また、必要に応じてメソッド単位での指定も可能です。プリフライト対応としてRequestMethod.OPTIONSを含めておくことで、OPTIONSメソッドにも対応できます。

このように、@CrossOriginは手軽にController CORS設定を行いたい場合に非常に便利な方法です。ただし、Spring Securityの設定が優先されるため、Security側でもcors()を有効にする必要があります。

5. プリフライトに対するレスポンスヘッダの設定と意味

5. プリフライトに対するレスポンスヘッダの設定と意味
5. プリフライトに対するレスポンスヘッダの設定と意味

プリフライトリクエストでは、サーバーから返されるレスポンスヘッダがとても重要です。これらのヘッダが適切に設定されていないと、ブラウザは本来のリクエストを送ることを許可しません。

主なレスポンスヘッダとその意味は以下の通りです:

  • Access-Control-Allow-Origin:許可されるオリジン(ドメイン)
  • Access-Control-Allow-Methods:許可されるHTTPメソッド(例:GET, POST, PUT, DELETE, OPTIONS)
  • Access-Control-Allow-Headers:許可されるリクエストヘッダ(例:Content-Type, Authorization)
  • Access-Control-Max-Age:プリフライト結果のキャッシュ時間(秒)

Springでは、これらのヘッダをCorsRegistry@CrossOriginで簡単に設定できます。例として、全体の設定を以下のようにまとめることができます。


@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
            .allowedOrigins("https://frontend.example.com")
            .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
            .allowedHeaders("Content-Type", "Authorization")
            .maxAge(3600);
    }
}

allowedHeadersを指定することで、Content-TypeAuthorizationなどのカスタムヘッダが使用可能になります。これは特に認証付きのAPIで重要です。

また、maxAgeを設定することで、ブラウザがプリフライト結果を一定時間キャッシュできるため、同じリクエストが何度もOPTIONSメソッドで確認されるのを防ぐことができます。

これらのレスポンスヘッダが正しく返されるようにController CORSやSpring Security CORS設定を組み合わせて構成することが、クロスオリジン通信の成功に不可欠です。

6. Spring Securityを導入しているときの注意点(SecurityFilterとの関係)

6. Spring Securityを導入しているときの注意点(SecurityFilterとの関係)
6. Spring Securityを導入しているときの注意点(SecurityFilterとの関係)

Spring Securityを使っているプロジェクトでは、CORS設定が少し複雑になります。SecurityFilterChainがCORSよりも先に動作する場合、正しく設定されていないとプリフライトリクエストがブロックされてしまうことがあります。

たとえば、CORSの許可設定をWebMvcConfigurerで書いたとしても、Spring Security側でcors()が有効になっていないと意味がありません。そのため、Securityの設定で必ず以下のようにcors()を有効化しておく必要があります。


@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .cors().and()
            .csrf().disable()
            .authorizeHttpRequests(auth -> auth
                .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                .anyRequest().authenticated()
            );
        return http.build();
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowedOrigins(List.of("https://frontend.example.com"));
        config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
        config.setAllowedHeaders(List.of("Content-Type", "Authorization"));
        config.setMaxAge(3600L);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return source;
    }
}

このように、Spring SecurityでCORS設定を明示することで、SecurityFilterChainより先にCORSフィルターが適用されるようになります。これがうまく動かないと、「プリフライトリクエスト エラー」や403エラーが発生する原因になります。

初心者の方は、Controller側だけでCORS設定をすればよいと思いがちですが、Spring SecurityとCORSの関係を理解して、フィルター順序の影響を意識しておくことが大切です。

7. プリフライトリクエストが失敗するときの原因と対処法

7. プリフライトリクエストが失敗するときの原因と対処法
7. プリフライトリクエストが失敗するときの原因と対処法

クロスオリジン通信で最も多いトラブルが、プリフライトリクエストの失敗です。初心者がつまずきやすいポイントをいくつか紹介し、それぞれの対処方法を解説します。

Access-Control-Allow-Originヘッダが不足している

これは基本中の基本ですが、プリフライトリクエストのレスポンスにAccess-Control-Allow-Originが設定されていないと、ブラウザは通信を拒否します。

対処法: @CrossOriginWebMvcConfigurer、もしくはcorsConfigurationSource()で正しくオリジンを指定しましょう。

② OPTIONSメソッドが許可されていない

Spring Securityの設定で、OPTIONSメソッドが認可されていない場合、403 Forbiddenエラーが発生します。

対処法: Security設定でrequestMatchers(HttpMethod.OPTIONS, "/**").permitAll()を追加して対応します。

③ リクエストヘッダが制限されている

クライアントから送信されるヘッダ(例:Content-Type: application/jsonAuthorization)が、Access-Control-Allow-Headersに含まれていない場合、プリフライトが拒否されます。

対処法: 必要なヘッダをallowedHeadersで明示的に許可してください。

Access-Control-Allow-MethodsにHTTPメソッドが含まれていない

リクエストしようとしているメソッド(例:PUTDELETE)がサーバー側で許可されていないと、リクエストはブロックされます。

対処法: allowedMethodsで、必要なHTTPメソッドをすべて指定してください。

8. ブラウザでの確認方法(開発者ツールを使ったCORSチェック)

8. ブラウザでの確認方法(開発者ツールを使ったCORSチェック)
8. ブラウザでの確認方法(開発者ツールを使ったCORSチェック)

CORSに関するエラーやプリフライトの動作確認は、ブラウザの開発者ツールを使うのが基本です。ここではGoogle Chromeを例に、確認手順を説明します。

① 開発者ツールの開き方

ブラウザでページを開いた状態で、右クリック →「検証」またはF12キーを押します。「開発者ツール」が表示されます。

② Networkタブで通信内容を確認

「Network」タブを選択してからページを再読み込みし、該当するリクエスト(例:/api/data)をクリックします。

リクエスト詳細の中に「Headers」タブがあり、Request HeadersResponse Headersを確認できます。

③ プリフライトリクエストの確認

OPTIONSメソッドによるプリフライトリクエストは、通常のリクエストの前に表示されます。以下のような点を確認しましょう:

  • ステータスコードが200であること
  • Access-Control-Allow-Originが正しく設定されていること
  • Access-Control-Allow-Methodsに目的のメソッドが含まれていること

これらを確認することで、Controller CORS設定が正しく反映されているかをチェックできます。

プリフライトリクエストの挙動は一見見えづらいですが、開発者ツールを使えば通信の裏側を視覚的に把握することができます

まとめ

まとめ
まとめ

今回の記事では、CORS(クロスオリジンリソースシェアリング)とプリフライトリクエスト、Spring SecurityにおけるOPTIONSメソッドの扱いについて、初心者向けに詳しく解説しました。CORSは、異なるオリジン間でのリソースアクセスを制御する仕組みであり、ブラウザのセキュリティ機能として重要です。特に、PUTやDELETEなど特殊なHTTPメソッドを使う場合や、Content-Typeにapplication/jsonなどのカスタムヘッダーを含むリクエストでは、プリフライトリクエストが発生します。この事前確認リクエストを正しく処理しないと、ブラウザは本来のリクエストをブロックしてしまい、403エラーや通信失敗の原因になります。

Spring BootやSpring MVC環境でプリフライトリクエストを正しく処理するには、まず@CrossOriginWebMvcConfigurerでCORS設定を行うことが基本です。そして、Spring Securityを導入している場合は、SecurityFilterChainにcors()を有効化し、requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()を追加することで、OPTIONSメソッドによるプリフライトリクエストを許可する必要があります。これにより、ControllerレベルでのAPI処理前にプリフライトがスムーズに通過し、クロスオリジン通信が安全かつ確実に行われます。

また、レスポンスヘッダの設定も非常に重要です。Access-Control-Allow-OriginAccess-Control-Allow-MethodsAccess-Control-Allow-HeadersAccess-Control-Max-Ageを適切に設定することで、ブラウザがリクエストを許可し、同じプリフライトリクエストが繰り返されるのを防ぐことができます。SpringのCorsRegistry@CrossOriginを活用すると、これらの設定を簡単に管理できます。

サンプルコードまとめ


@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .cors().and()
            .csrf().disable()
            .authorizeHttpRequests(auth -> auth
                .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                .anyRequest().authenticated()
            );
        return http.build();
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowedOrigins(List.of("https://frontend.example.com"));
        config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
        config.setAllowedHeaders(List.of("Content-Type", "Authorization"));
        config.setMaxAge(3600L);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return source;
    }
}

@Controller
@CrossOrigin(
    origins = "https://frontend.example.com",
    methods = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE, RequestMethod.OPTIONS}
)
public class ApiController {

    @PostMapping("/api/data")
    @ResponseBody
    public String postData() {
        return "データを受け取りました";
    }
}

これらの設定により、プリフライトリクエストが正しく処理され、クロスオリジン通信が安全に実行できるようになります。特に、Spring Security環境下では、CORS設定がSecurityFilterChainよりも先に適用されるように意識することが重要です。開発者ツールを活用して、リクエストとレスポンスのヘッダを確認しながら設定を進めると、初心者でも安全なAPI通信を実現できます。

先生と生徒の振り返り会話

新人

「プリフライトリクエストが何で必要なのか、やっと理解できました。ブラウザが勝手にOPTIONSで確認しているんですね。」

先輩

「そうだね。それを許可しないと、POSTやPUTのリクエストが全てブロックされてしまうから、SecurityFilterとCORS設定の順序が重要なんだ。」

新人

「なるほど、Controllerで@CrossOriginだけ設定しても、SecurityFilterChainが先に動くと意味がないんですね。」

先輩

「その通り。だからSpring Security側でcors()を有効にして、OPTIONSメソッドを許可する設定が必要なんだ。これでプリフライトがスムーズに通る。」

新人

「レスポンスヘッダもきちんと設定しないといけないんですね。Access-Control-Allow-OriginAccess-Control-Allow-Methodsなどですね。」

先輩

「そう。ヘッダを正しく設定することで、ブラウザが安全にリクエストを送れるようになる。開発者ツールで確認しながら設定すると安心だよ。」

新人

「これで、CORSとプリフライトリクエスト、Spring Securityの関係がはっきり理解できました!」

先輩

「よく理解できたね。今回学んだことを踏まえて、実務でも安全にクロスオリジン通信を扱えるように練習してみよう。」

コメント
コメント投稿は、ログインしてください

まだ口コミはありません。

カテゴリの一覧へ
新着記事
New1
Spring認証(Spring Security)
Spring BootでCORSを設定する方法を完全解説!初心者でもわかるセキュリティ対策
New2
Spring認証(Spring Security)
パスワードをハッシュ化する理由とは?セキュリティ対策の基本をSpring Securityで学ぼう
New3
SpringのWeb開発(Spring MVC)
HTTPリクエストとレスポンスの基本を完全解説!Spring MVC初心者がWeb通信の仕組みをやさしく理解
New4
Spring認証(Spring Security)
ブラウザからのフォーム送信とは?HTTPリクエストの基礎を初心者向けに解説!
人気記事
No.1
Java&Spring記事人気No1
SpringのWeb開発(Spring MVC)
ルーティングとは?基本概念(Spring MVCのURL制御を理解)
No.2
Java&Spring記事人気No2
Thymeleaf
Thymeleaf とは?初心者向けにThymeleafの基本を徹底解説
No.3
Java&Spring記事人気No3
Springの基本
application.properties と YAML の基本をやさしく解説!初心者向けSpring Boot設定ファイル入門
No.4
Java&Spring記事人気No4
Springの基本
Spring Bootのデフォルトログ設定を徹底解説(Logback / SLF4J)
No.5
Java&Spring記事人気No5
Springの基本
Spring Bootの環境変数の設定方法をやさしく解説!初心者向けapplication.propertiesの使い方
No.6
Java&Spring記事人気No6
SpringのWeb開発(Spring MVC)
ループ処理(th:each)の基本を完全ガイド!Thymeafの繰り返し処理の使い方
No.7
Java&Spring記事人気No7
SpringのDB操作
JPAの標準クエリメソッド(findById, findAll)を完全解説!初心者でもわかるデータ取得の基本
No.8
Java&Spring記事人気No8
Spring認証(Spring Security)
セッション管理の基本(@SessionAttributes)を完全解説!初心者でもわかるセッションの仕組み