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;
}
両方が同様の結果を生成できるように見えます。質問は違いは何ですか?どちらを使用するか?
答えはあなたの質問の中にあります。別の認証システムを使用しており、パスワードが独自のデータベース/データモデルで提供されていない場合は、AuthenticationProviderを使用する必要があります。たとえば、顧客が集中認証システム(CAS)を使用しているプロジェクトで働いていたため、システムにパスワードがわからなかったため、AuthenticationProviderを実装し、指定されたパスワードをCASに送信し、その答えに。
しかし、別のシステムでは、パスワードをデータベースに保存していたので、UserDetailsServiceを実装し、ユーザーがデータベースに存在するかどうかを確認するだけで、spring-securityが残りを行う必要がありました。
Spring Securityのドキュメントから https://docs.spring.io/spring-security/site/docs/5.0.0.RC1/reference/htmlsingle/#overall-architecture
UserDetailsServiceについては、しばしば混乱が生じます。これは純粋にユーザーデータのDAOであり、そのデータをフレームワーク内の他のコンポーネントに提供すること以外の機能は実行しません。特に、AuthenticationManagerによって行われるユーザーの認証は行いません。多くの場合、カスタム認証プロセスが必要な場合は、AuthenticationProviderを直接実装する方が適切です。
AuthenticationProviderとUserDetailsServiceの目的は異なります。
AuthenticationProviderは、システムユーザーに対してユーザー(要求)が提供したユーザー名とパスワードを認証(比較)します(これは、登録済みユーザーのリストを保持するDBのような任意のシステムです)
ユーザー指定のユーザー名と一致するシステムユーザーの詳細を取得するのは、UserDetailsService実装の責任です。ここでは、同じユーザー名を持つユーザーを取得するだけで、認証が成功したか失敗したかをアプリケーションに通知しません。
例:Springは、データベースに対してユーザーの詳細を認証するためのデフォルトのセットアップとして以下を提供します
よりよく理解するには、こちらをご覧ください。
AuthenticationProvider- DaoAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider
UserDetailsService- JdbcDaoImpl
UserDetails- ユーザー
これら2つは関連していますが、意図的にSpring Securityによって分離されています。企業に複数のシステムがある場合、認証が完全に別のシステムによって実行される場合でも、UserDetailsServiceは特定のシステムが保持する特定のユーザーの情報を提供します。単純なシステムでは、それらを組み合わせることができます。たとえば、データベースコールはユーザー名/パスワードを検証し、そのユーザーのメール、IDなどをすべて取得します。
Spring Security Referenceによると: http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#getting-started
UserDetailsServiceについては、しばしば混乱が生じます。これは純粋にユーザーデータのDAOであり、そのデータをフレームワーク内の他のコンポーネントに提供すること以外の機能は実行しません。特に、AuthenticationManagerによって行われるユーザーの認証は行いません。多くの場合、カスタム認証プロセスが必要な場合は、AuthenticationProviderを直接実装する方が理にかなっています。