Help us understand the problem. What is going on with this article?

Spring Security認証周りについて

More than 1 year has passed since last update.

概要

Spring Securityの認証まわりについて調べたので備忘録です。

概略図

Screen Shot 2019-08-14 at 19.52.18.png

リクエストに対して、SecurityFilterChainが適用されます。
認証に関してはデフォルトではUsernamePasswordAuthenticationFilterが担当します(指定パスに対して適用、例:/loginなど)。
FilterからAuthenticationManagerが呼ばれ認証の可否を決定します。
AuthenticationManagerは複数のAuthenticationProviderを持ち、各Providerに対して認証可否の処理を委譲します。

AuthenticationFilter

認証処理を行うURLに対して適用されます。
ユーザー入力のnullチェックを行い、入力情報を元にUsernamePasswordAuthenticationTokenを発行、Managerに対して、認証可否を委譲します。
※通常、パラメータはID、パスワードのみとなっているので、それ以上のパラメータを使用して認証を行う場合は、カスタムフィルターを作成します。

UsernamePasswordAuthenticationToken

AbstractAuthenticationTokenを継承した入力値と認証判断に使用するフィールドパラメータを持ったデータオブジェクトです。
各Providerはこのオブジェクトを受け取り、フィールドパラメータから認証可否を判断します。

AuthenticationManager

インターフェースorg.springframework.security.authentication.AuthenticationManagerです。
このインターフェースには1つだけメソッドが定義されています。

AuthenticationManager.java
Authentication authenticate(Authentication authentication)
            throws AuthenticationException;

デフォルトの実装クラスはorg.springframework.security.authentication.ProviderManagerです。

ProviderManagerは実際にパスワード一致などの判定を行うAuthenticationProviderを配列で持っており、各Providerのauthenticateメソッドを呼び、認証判定を行います。

AuthenticationProvider

実際に認証判定を行うクラスです(例 パスワード一致など)。
前述の通り、Providerは複数登録することが可能です。

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authProvider());
        auth.authenticationProvider(authProvider2());
    }

    public AuthenticationProvider authProvider() {
        return new AbstractUserDetailsAuthenticationProvider() {

            @Override
            protected void additionalAuthenticationChecks(UserDetails userDetails,
                UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
              // 
            }

            @Override
            protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication)
                throws AuthenticationException {
                // ログインに使用したい特定のユーザーを作成する処理
                return user;
            }
        };
    }

あまり使い時はないかもしれませんが、ProviderでUserDetailsを継承したユーザーを返すようにすると、
インメモリ認証のようにすることもできます。

Providerの登録はWebSecurityConfigurerAdapterを継承したコンフィグクラス下でBeanアノテーションをつけるだけでも良いです。

    @Bean
    public AuthenticationProvider authProvider() {
        return new CustomAuthenticationProvider(passwordEncoder, authenticationService);
    }

ProviderのretrieveUserメソッド内でDBへのユーザー情報を取得し、パスワードの一致確認を行うことで認証可否の判断を行います。

以上、簡単ですがまとめでした。
内部実装を見てみるとパスワードハッシュに対するタイミング攻撃対策などがあり興味深いですね。

SpringSecurity全体のまとめはこちらの記事が参考になります。
Spring Security 使い方メモ 基礎・仕組み

nannou
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした