daisuzz.log

Spring Securityを使ってエンドポイントに応じて複数の認証方式を切り替える方法

Spring Securityを使ったAPIを実装していたときに、REST APIにはBASIC認証をかけて、画面にはフォーム認証をかける、ということがやりたくなったのでその方法を備忘録として書いておきます。

環境

  • Spring Boot 2.7
  • Kotlin 1.6.21

方法

/api/から始まるREST APIのエンドポイントにはBASIC認証を、それ以外の画面を返すエンドポイントにはフォーム認証をかけるための設定は以下。

@Configuration
class SecurityConfiguration {

    @Bean
    @Order(1)
    fun apiFilterChain(http: HttpSecurity): SecurityFilterChain {
        http {
            securityMatcher("/api/**")
            httpBasic { }
            authorizeRequests {
                authorize("/api", authenticated)
                authorize(anyRequest, permitAll)
            }
        }
        return http.build()
    }

    @Bean
    fun filterChain(http: HttpSecurity): SecurityFilterChain {
        http {
            formLogin { }
            authorizeRequests {
                authorize("/", authenticated)
                authorize(anyRequest, permitAll)
            }
        }
        return http.build()
    }
}

SecurityFIlterChainのBean定義を2つ用意して、1つはOrder(1)を設定することで優先的に読み込まれるようにしておく。

優先的に読み込まれるSecurityFilterChainのBean定義には、securityMatcher()というメソッドでどのエンドポイントのときに設定を有効にするのか?ということを設定しておく。

こうすることで、最初に読み込まれたapiFilterChain()でエンドポイントが/api/から始まるものにはBASIC認証をかけるSecurityFilterChainが登録され、次のfilterChainでそれ以外のエンドポイントにフォーム認証をかけるSecurityFilterChainがDIコンテナに登録される。

サンプルコードは以下

github.com

参考資料

Kotlin Configuration :: Spring Security

Spring Security without the WebSecurityConfigurerAdapter