CORS
CORS (Cross Origin Resource Sharing) はHTTPヘッダーを使用して異なるオリジン間でリソースを共有する仕組み。サーバーがクライアントのリクエストに対して以下のヘッダーを用いて応答し、どのオリジンに対して許可しているかを示す。
Access-Control-Allow-Origin
アクセス可能な外部のドメインを指定Access-Control-Allow-Methods
アクセス可能なHTTPメソッドを指定Access-Control-Allow-Headers
外部ドメインで使用するヘッダを制限する
CORSは認証や認可のように特定のエンドポイントを保護する仕組みではない。異なるドメイン間の呼び出しの制限を緩和する仕組みになる。なので、CORSを許可していないエンドポイントを呼び出すこと自体は可能になる。
注意しなくてはいけないのはCORSはあくまでもクライアント(ブラウザ)のセキュリティであり、リクエストを受け取るサーバーはCORSの設定有無に関わらずリクエストの認証認可、サニタイジングを行わなくてはいけない。よくある誤解としてCORSにより許可されていないリクエストはサーバーで処理されないと思われがちだが、それは間違いである。
サンプルコード
SpringSecurityでCORSの設定をするには以下のようにする。
@RestController public class MainController { private Logger logger = Logger.getLogger(MainController.class.getName()); @PostMapping("/test") @CrossOrigin("http://localhost:8080") public String test() { logger.info("Test method called"); return "method called"; } }
SpringSecurityでは @CrossOrigin
をコントローラーのメソッドにつけることでCORSのヘッダーをレスポンスに追加できる。上記の例では localhost:8080
ドメインのリソースから呼び出すことができることを示している。
オリジン
CORSでは同一オリジンポリシーに従って制限を行う。同一オリジンポリシーとはオリジンが同じか、違うのかを定めるものであり、オリジンの定義に基づく。オリジンとはプロトコル、ポート番号、ホストの組み合わせのことでこれらが一つでも異なるものは同一のオリジンとは判断されない。
例えば以下のオリジンがあったとする。
http://example.com/index.html
上記のオリジンと同一オリジンと判断されるのは以下のようなオリジンになる。プロトコル(http)、ポート番号(省略のためウェルノウンポートの80)、ホスト(example.com)が同じになる。パスは異なるが、オリジンの定義にパスは含まれていないので異なるパスであっても同一オリジンとして判断される。
https://ja.wikipedia.org/wiki/TCPやUDPにおけるポート番号の一覧
http://example.com/admin/users.html
異なるドメインと判断されるのは例えば以下のようにプロトコルが異なる場合などになる。
https://example.com/index.html
外部リンク
CORSについて参考にしたサイトはこちら。ここでは書いていないが単純リクエストとプリフライトリクエスト、資格情報を含むリクエストについても重要な情報だと思う。