daisuzz.log

Spring Securityを使ったモック認証処理を実装する

Spring Securityを使った認証処理を実装したアプリケーションにおいて、モックの認証情報を使って動作確認をする方法を書いていきます。 認証処理の実装と、認証対象の画面や機能の実装が並行して行われているときに、Spring Securityの仕組みを使いつつもモックの認証情報を使える形にしておくことで、認証対象の画面や機能の動作確認をスムーズに行うことができます。

実現したいこと

  • Spring Securityの認証の仕組みを利用してフォーム認証でログインできること
  • 認証情報に含まれるユーザ名を画面に表示したい
  • ローカルで動作確認をする際にモックとして固定値の認証情報を使いたい

環境

  • Kotlin 1.6.21
  • Spring Boot 2.6.7

方法

モックの認証情報を返すAuthenticationProviderを実装して、Spring Securityの認証処理でこのAuthenticationProviderを利用するよう実装していきます。

AuthenticationProviderの実装

Spring SecurityではAuthenticationProviderインターフェースの実装クラスで認証を行いユーザの認証情報(UserDetails)を返す仕組みになっています。 そこで、この仕組みを利用して必ずモックの認証情報を返すMockAuthenticationProviderを実装します。

@Component
class MockAuthenticationProvider : AuthenticationProvider {
    override fun authenticate(authentication: Authentication): Authentication {
        val mockUser = User(authentication.name, authentication.credentials.toString(), listOf())
        return UsernamePasswordAuthenticationToken(mockUser, "", mockUser.authorities)
    }

    override fun supports(authentication: Class<*>?): Boolean {
        return authentication == UsernamePasswordAuthenticationToken::class.java
    }
}

authenticateメソッドが呼ばれると、ユーザが入力した認証情報をUserというUserDetailsインターフェースの実装クラスに詰めて、UsernamePasswordAuthenticationTokenを返す形になっています。 この実装にすることで、ログインフォームにどんな情報を入力しても認証は成功し、ログインユーザ名は入力したユーザ名がセットされます。

SecurityConfigurationの実装

Spring Securityの認証の仕組みでこのAuthenticationProviderを利用するために、JavaConfigを実装します。

@Configuration
class SecurityConfiguration {

    @Bean
    fun filterChain(
        http: HttpSecurity,
        mockAuthenticationProvider: MockAuthenticationProvider
    ): SecurityFilterChain {
        http {
            authorizeRequests {
                authorize(anyRequest, authenticated)
            }
            formLogin { }
            logout {
                logoutUrl = "/logout"
            }
        }
        http.authenticationProvider(mockAuthenticationProvider)

        return http.build()
    }
}

KotlinDSLではAuthenticationProviderをセットするメソッドが提供されていないため、DSLではなくauthenticationProviderメソッドを使ってAuthenticationProviderをセットしています。

その他画面やControllerの実装は以下サンプルコードを参照してください。

github.com

サンプルコードを起動後、localhost:8080/loginにアクセスして、ログインが成功するとログインフォームで入力したユーザ名が画面に表示されます。