少し前にSpring Bootアプリケーションを開発し、ローカルデータベースを使用してユーザー認証を行いました。
アプリケーションがどんどん使われるようになったので、会社のActive Directoryを介した認証も有効にしたいと思います。
ローカルユーザーテーブルにすべてのユーザーを保持して他のテーブルから参照できるようにしたいが、一部のユーザーのアクティブディレクトリに対してユーザー名とパスワードを確認します。ユーザーがActive Directoryユーザーであるかローカルユーザーであるかは、ユーザーテーブルに保持されます。
疑似コードでは、次のようになります。
if(user.isAdUser()) {
checkCredentialsAgainstAD();
} else {
checkCredentialsAgainstLocalDb();
}
現在の認証コードは次のようになります。
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDAO userDao;
@Override
protected void configure(HttpSecurity http) throws Exception {
/* http.authorizeRequests()... */
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(new CustomUserDetailsService(userDao)).passwordEncoder(new BCryptPasswordEncoder());
}
}
userDao
オーバーライドされたloadUserByUsername(String username)
メソッドで、データベースからユーザー情報をロードします。
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userDao.readUserByLogin(username, true);
if(user == null){
log.info(username + " not found");
throw new UsernameNotFoundException(username + " not found");
}
User userObj = user.clone();
userObj.password = null;
return new CustomUserDetails(user.loginName, user.password, getAuthorities(user), userObj);
}
ActiveDirectoryLdapAuthenticationProvider
このようなものを追加できることはすでにわかりました
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(new ActiveDirectoryLdapAuthenticationProvider("DOMAIN", "ldap://example.com")).userDetailsService(new CustomUserDetailsService(userDao)).passwordEncoder(new BCryptPasswordEncoder());
})
しかし、それは常にActive Directoryを使用します。
使用する認証プロバイダーを具体的にどのように選択できますか?
Java Spring Securityの構成で推奨されている順序ですべてのプロバイダーをテストしたくありません-複数の認証プロバイダーですが、データベースから取得したフラグに応じて、正しいプロバイダーのみをテストします。
あなたの要件に基づいて、おそらく最も簡単な解決策はAuthenticationProvider
、DaoAuthenticationProvider
との両方を内部的にラップするカスタムを作成することActiveDirectoryLdapAuthenticationProvider
です。
このカスタムのみAuthenticationProvider
が登録されます。認証中に、最初にユーザーをDBから取得して「認証モード」を決定し、さらに認証を委任するDaoAuthenticationProvider
か、またはActiveDirectoryLdapAuthenticationProvider
それに応じて委任します。
以下のようなものを自由に変更してください:
@Service
public class MyCustomAuthenticationProvider implements AuthenticationProvider{
@Autowired
private DaoAuthenticationProvider dbAuthProvider;
@Autowired
private ActiveDirectoryLdapAuthenticationProvider adAuthProvider;
@Autowired
UserDAO userDao;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException{
// Determine username
String username = (authentication.getPrincipal() == null) ? "NONE_PROVIDED": authentication.getName();
User user = userDao.getUserByName(username);
if(user == null){
throw new AuthenticationException("Sorry. No this user.");
}
if(user.isAdUser()) {
return adAuthProvider.authenticate(authentication);
} else {
return dbAuthProvider.authenticate(authentication);
}
}
@Override
public boolean supports(Class<?> authentication){
return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
}
}
しかし、注釈付き構成によってそれらを配線する方法は、フォローアップする必要がある別の話です.....
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加