Works by

Ren's blog

アプリケーションバックエンド中心に書いていきます

【Spring】Spring SecurityでCORS設定をする

f:id:rennnosukesann:20181220183020p:plain:w500

Spring SecurityでCORSを使用した設定を行う方法を紹介します。

Spring Securityを導入することで、Springアプリケーションに手軽に認証・認可を仕組みを設定することができますが、認可の一環としてCORSの設定も行うことができます。


例えば、以下のような yaml ファイルに記述したクライアントドメインを許可したいとします。

security:
  corsClientUrls:
    - http://localhost:3000
    - http://localhost:8080

このとき、 CORSは WebSevurityConfigurerAdapter 派生Beanクラスを定義して設定します。

なお上記yamlファイル上のドメイン@ConfigurationProperties アノテーションによって下記 SecurityConfig プロパティとして読み込まれ、 corsClientUrls に挿入されます。

@Configuration
@EnableWebSecurity
@ConfigurationProperties(prefix = "security")
class SecurityConfig : WebSecurityConfigurerAdapter() {
    
    // 許可するドメイン
    lateinit var corsClientUrls: List<String>

    override fun configure(http: HttpSecurity?) {
        http
            // ...
            // 諸々の設定
            // ...
            ?.and()
            ?.cors()
            ?.configurationSource(getCorsConfigurationSource()) //CORS設定
    }

上記コードでは、まず認証・認可について設定する WebSecurityConfigurerAdapter 派生クラスを定義し、メソッド configuration の引数 HttpSecurity にCORSのルールを設定しています。

具体的には、 HttpSecurity::cors()CorsConfigurer インスタンスを返し、この型が CorsConfigurer::configurationSource() メソッドを持っているのですが、このメソッドに CorsConfigurationSource インスタンスを渡してあげるとCORSについての設定をSpringのHTTPリクエスト・レスポンスに反映させることができます。

上記の例では、 getCorsConfigurationSource()CorsConfigurationSource インスタンスを返していることになります。

では、その getCorsConfigurationSource() の中身を見てみましょう。

    /**
     * CORS設定
     */
    fun getCorsConfigurationSource(): CorsConfigurationSource {

        val corsConfiguration = CorsConfiguration()
        
        // ①CORSを許可するURLの登録(Access-Control-Allow-Origin) 
        this.corsClientUrls.forEach { corsConfiguration.addAllowedOrigin(it) }

        // ②許可するHeaderの登録(Access-Control-Allow-Headers)
        corsConfiguration.addAllowedHeader(CorsConfiguration.ALL)
        
        // ③許可するMethodの登録(Access-Control-AllowMethods)
        corsConfiguration.addAllowedMethod(CorsConfiguration.ALL)
        
        // ④認証情報送信許可の登録(Access-Control-Allow-Credentials)
        corsConfiguration.allowCredentials = true

        val corsSource = UrlBasedCorsConfigurationSource()

        // どのパスに上記ルールを適用するか
        corsSource.registerCorsConfiguration("/**", corsConfiguration)

        return corsSource
    }

getCorsConfigurationSource() では、HTTPレスポンスヘッダ設定を CorsConfiguration インスタンスに詰めていき、
それを CorsConfigurationSource インスタンスに持たせています(実際には UrlBased orsConfigurationSourceを使用しています )。

上記コードでは、以下の4ヘッダーを設定しています。

①Access-Control-Allow-Origin: ...
②Access-Control-Allow-Headers: ...
③Access-Control-Allow-Methods: ...
④Access-Control-Allow-Credentials: ...

①にCORSを許可したいドメイン(オリジン)を、
②にCORS中で許可したいHTTPヘッダを、
③にCORS中で許可したいHTTPメソッドを、
④にCORS中での認証情報(BASIC認証情報やクッキーなど)の受け渡し許可有無を、
設定します。

参考文献

docs.spring.io