1. Security のコア概念

Spring Security の本質は フィルターチェーン(Filter Chain) であり、内部には異なる機能を提供する複数のフィルターが含まれています。基本的なアプリケーションにおいて、フィルターチェーンの主要なフィルターは以下のとおりです:
- UsernamePasswordAuthenticationFilter:ユーザー名とパスワードに基づくログインリクエストを処理し、ユーザー認証を担当する。
-
ExceptionTranslationFilter:フィルターチェーン内で発生した
AccessDeniedExceptionやAuthenticationExceptionをキャッチし、適切に処理する。 - FilterSecurityInterceptor:アクセス制御の決定を担当し、ユーザーが保護されたリソースにアクセスする権限を持っているかどうかを検証する。
Spring Security のフィルターチェーンの具体的な構成や実行順序は、デバッグモードで確認できます。
2. Security 認証プロセス
2.1 Security 設定クラス
Spring Security 5.7 以降では、WebSecurityConfigurerAdapter を継承するのではなく、SecurityFilterChain を使用してセキュリティポリシーを設定することが推奨されています。
@Configuration
public class WebSecurityConfig {
@Bean
public UserDetailsService userDetailsService() {
// ユーザーオブジェクトを作成
UserDetails user = User.withUsername("Tanaka")
.password("{noop}111111") // `{noop}` は暗号化なし
.roles("USER")
.build();
// InMemoryUserDetailsManager を作成し、ユーザー情報を登録
InMemoryUserDetailsManager userDetailsManager = new InMemoryUserDetailsManager();
userDetailsManager.createUser(user);
// UserDetailsService を返し、Spring Security に管理させる
return userDetailsManager;
}
}
UserDetailService インターフェースに入ると、重要なメソッドがあり、次に使用されます

2.2 認証プロセス(Authentication)
1. ユーザーがログインリクエストを送信
ユーザーがフォームログインを行う際、Spring Security に組み込まれている UsernamePasswordAuthenticationFilter フィルターが POST /login リクエストをキャッチし、attemptAuthentication メソッドを呼び出します。

次に AbstractAuthenticationProcessingFilter メソッドに進みます。

このフィルターが実行され、attemptAuthentication メソッドに入ります。
2. 認証オブジェクトの作成
UsernamePasswordAuthenticationFilter はリクエストパラメータを解析し、UsernamePasswordAuthenticationToken を使用してユーザーの認証情報(ユーザー名とパスワード)をカプセル化します。
Authentication authentication = new UsernamePasswordAuthenticationToken(username, password);
3. AuthenticationManager による認証処理
AuthenticationManager(デフォルト実装は ProviderManager)は Authentication オブジェクトを受け取り、AuthenticationProvider に委託して認証を行います。
Authentication authenticationResult = authenticationManager.authenticate(authentication);
4. AuthenticationProvider による認証処理
ProviderManager は内部で複数の AuthenticationProvider を管理しており、デフォルトでは DaoAuthenticationProvider が使用されます。
5. ユーザー情報のロード(UserDetailsService)
DaoAuthenticationProvider は UserDetailsService#loadUserByUsername() メソッドを呼び出し、メモリやデータベースからユーザー情報をロードします。
@Override
protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) {
return this.userDetailsService.loadUserByUsername(username);
}
6. パスワードの検証
DaoAuthenticationProvider は PasswordEncoder#matches() メソッドを使用して、入力されたパスワードと保存されているパスワードを比較します。
@Override
protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) {
if (!passwordEncoder.matches(authentication.getCredentials().toString(), userDetails.getPassword())) {
throw new BadCredentialsException("Invalid password");
}
}
7. 認証結果の処理
-
認証成功:
-
Authenticationオブジェクトが作成され、SecurityContextHolderに設定される。 -
AuthenticationSuccessHandlerがトリガーされ、(デフォルトでは元のアクセスページまたはホームページにリダイレクト)。
認証失敗:
-
AuthenticationFailureHandlerがトリガーされ、認証失敗のレスポンスを返す。
-
if (authentication.isAuthenticated()) {
SecurityContextHolder.getContext().setAuthentication(authentication);
}

















