web-dev-qa-db-ja.com

Spring Securityのカスタム認証-AuthenticationProvider vs UserDetailsS​​ervice

Spring Securityでカスタム認証が必要な場合を理解できる限り、カスタムAuthenticationProviderまたはcustom UserDetailsServiceを実装できます。

@Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth    
            //.authenticationProvider(authProvider)  // option 1
            .userDetailsService(userDetailsService); // option 2

    }

AuthenticationProviderでは、ユーザー名とパスワードを確認し、カスタムオブジェクトを含むAuthenticationを返すことができます。

public Authentication authenticate(Authentication authentication){
        if (checkUsernameAndPassword(authentication)) {
            CustomUserDetails userDetails = new CustomUserDetails();
            //add whatever you want to the custom user details object
            return new UsernamePasswordAuthenticationToken(userDetails, password, grantedAuths);
        } else {
            throw new BadCredentialsException("Unable to auth against third party systems");
        }
    }

UserDetailsServiceではユーザー名のみを取得し、カスタムUserDeatailsを返すと、フレームワークはパスワードのチェックを実行します。

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        CustomUserDetails user = new CustomUserDetails();
        //add whatever you want to the custom user details object
        return user;
    }

両方が同様の結果を生成できるように見えます。質問は違いは何ですか?どちらを使用するか?

32
Evgeni Dimitrov

答えはあなたの質問の中にあります。別の認証システムを使用しており、パスワードが独自のデータベース/データモデルで提供されていない場合は、AuthenticationProviderを使用する必要があります。たとえば、顧客が集中認証システム(CAS)を使用しているプロジェクトで働いていたため、システムにパスワードがわからなかったため、AuthenticationProviderを実装し、指定されたパスワードをCASに送信し、その答えに。

しかし、別のシステムでは、パスワードをデータベースに保存していたので、UserDetailsS​​erviceを実装し、ユーザーがデータベースに存在するかどうかを確認するだけで、spring-securityが残りを行う必要がありました。

33
Hossein

Spring Securityのドキュメントから https://docs.spring.io/spring-security/site/docs/5.0.0.RC1/reference/htmlsingle/#overall-architecture

UserDetailsS​​erviceについては、しばしば混乱が生じます。これは純粋にユーザーデータのDAOであり、そのデータをフレームワーク内の他のコンポーネントに提供すること以外の機能は実行しません。特に、AuthenticationManagerによって行われるユーザーの認証は行いません。多くの場合、カスタム認証プロセスが必要な場合は、AuthenticationProviderを直接実装する方が適切です。

AuthenticationProviderとUserDetailsS​​erviceの目的は異なります。

AuthenticationProviderは、システムユーザーに対してユーザー(要求)が提供したユーザー名とパスワードを認証(比較)します(これは、登録済みユーザーのリストを保持するDBのような任意のシステムです)

ユーザー指定のユーザー名と一致するシステムユーザーの詳細を取得するのは、UserDetailsS​​ervice実装の責任です。ここでは、同じユーザー名を持つユーザーを取得するだけで、認証が成功したか失敗したかをアプリケーションに通知しません。

例:Springは、データベースに対してユーザーの詳細を認証するためのデフォルトのセットアップとして以下を提供します

  • AuthenticationProvider-ユーザー名、認証オブジェクトを渡すことで認証メソッドを呼び出すAbstractUserDetailsAuthenticationProviderを拡張するDaoAuthenticationProvider
  • UserDetailsS​​ervice-JdbcDaoImpl
  • 認証の流れ
  1. DaoAuthenticationProviderの責任は、データベースユーザーのリクエストから取得したユーザー名とパスワードを認証することです。
  2. 対応するデータベースユーザーを取得するには、UserDetailsS​​ervice Implementataion JdbcDaoImplに、リクエストユーザー名と同じ名前のデータベースからUserDetailオブジェクトを取得するように要求します。ここで、JdbcDaoImplは、システムからUserDetailsオブジェクトを取得するだけです。そのユーザーは見つかりません。
  3. DBでユーザーの詳細が見つかった場合、DaoAuthenticationProviderは要求されたユーザーのパスワードをDBで確認し、それ以外の場合は認証に失敗します。
  4. DaoAuthenticationProviderは、JdbcDaoImpl応答に基づいてユーザーが認証されているかどうかに応じて応答します。

よりよく理解するには、こちらをご覧ください。

AuthenticationProvider- DaoAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider

UserDetailsS​​ervice- JdbcDaoImpl

UserDetails- ユーザー

10

これら2つは関連していますが、意図的にSpring Securityによって分離されています。企業に複数のシステムがある場合、認証が完全に別のシステムによって実行される場合でも、UserDetailsS​​erviceは特定のシステムが保持する特定のユーザーの情報を提供します。単純なシステムでは、それらを組み合わせることができます。たとえば、データベースコールはユーザー名/パスワードを検証し、そのユーザーのメール、IDなどをすべて取得します。

Spring Security Referenceによると: http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#getting-started

UserDetailsS​​erviceについては、しばしば混乱が生じます。これは純粋にユーザーデータのDAOであり、そのデータをフレームワーク内の他のコンポーネントに提供すること以外の機能は実行しません。特に、AuthenticationManagerによって行われるユーザーの認証は行いません。多くの場合、カスタム認証プロセスが必要な場合は、AuthenticationProviderを直接実装する方が理にかなっています。

2
Denis Wang