0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SpringSecurity6 メモリベースのユーザー認証ソースコード解析

Posted at

1. Security のコア概念

image-20250218133500811.png
Spring Security の本質は フィルターチェーン(Filter Chain) であり、内部には異なる機能を提供する複数のフィルターが含まれています。基本的なアプリケーションにおいて、フィルターチェーンの主要なフィルターは以下のとおりです:

  • UsernamePasswordAuthenticationFilter:ユーザー名とパスワードに基づくログインリクエストを処理し、ユーザー認証を担当する。
  • ExceptionTranslationFilter:フィルターチェーン内で発生した AccessDeniedExceptionAuthenticationException をキャッチし、適切に処理する。
  • FilterSecurityInterceptor:アクセス制御の決定を担当し、ユーザーが保護されたリソースにアクセスする権限を持っているかどうかを検証する。

Spring Security のフィルターチェーンの具体的な構成や実行順序は、デバッグモードで確認できます。

img

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 インターフェースに入ると、重要なメソッドがあり、次に使用されます
image-20250218091145800.png

2.2 認証プロセス(Authentication)

1. ユーザーがログインリクエストを送信

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

image-20250218091344283.png
次に AbstractAuthenticationProcessingFilter メソッドに進みます。
image-20250218091528234.png
このフィルターが実行され、attemptAuthentication メソッドに入ります。

2. 認証オブジェクトの作成

UsernamePasswordAuthenticationFilter はリクエストパラメータを解析し、UsernamePasswordAuthenticationToken を使用してユーザーの認証情報(ユーザー名とパスワード)をカプセル化します。

Authentication authentication = new UsernamePasswordAuthenticationToken(username, password);

image-20250218091712197.png

3. AuthenticationManager による認証処理

AuthenticationManager(デフォルト実装は ProviderManager)は Authentication オブジェクトを受け取り、AuthenticationProvider に委託して認証を行います。

Authentication authenticationResult = authenticationManager.authenticate(authentication);

image-20250218091750954.png

4. AuthenticationProvider による認証処理

ProviderManager は内部で複数の AuthenticationProvider を管理しており、デフォルトでは DaoAuthenticationProvider が使用されます。

image-20250218093104764.png

image-20250218093248946.png

image-20250218093622031.png

5. ユーザー情報のロード(UserDetailsService)

DaoAuthenticationProviderUserDetailsService#loadUserByUsername() メソッドを呼び出し、メモリやデータベースからユーザー情報をロードします。

@Override
protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) {
    return this.userDetailsService.loadUserByUsername(username);
}

image-20250218093414008.png

image-20250218093714270.png

image.png

image-20250218094415937.png

6. パスワードの検証

DaoAuthenticationProviderPasswordEncoder#matches() メソッドを使用して、入力されたパスワードと保存されているパスワードを比較します。

@Override
protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) {
    if (!passwordEncoder.matches(authentication.getCredentials().toString(), userDetails.getPassword())) {
        throw new BadCredentialsException("Invalid password");
    }
}

image-20250218094548117.png

image-20250218094656562.png

7. 認証結果の処理

  • 認証成功

    • Authentication オブジェクトが作成され、SecurityContextHolder に設定される。
    • AuthenticationSuccessHandler がトリガーされ、(デフォルトでは元のアクセスページまたはホームページにリダイレクト)。

    認証失敗

    • AuthenticationFailureHandler がトリガーされ、認証失敗のレスポンスを返す。
if (authentication.isAuthenticated()) {
    SecurityContextHolder.getContext().setAuthentication(authentication);
}

image-20250218094744688.png

image-20250218095243524.png

image-20250218100454943.png

image-20250218100510014.png

image-20250218100807659.png

3. 各オブジェクト間の関係

file_1739858115906_453.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?