さて、サミュエルの投稿で述べられているように、認証と承認を分離することは本当に役に立ちました。ただし、まだ多くの落とし穴があり、春にはユーザーに新しい役割を追加する簡単な方法がないため、認証解除は依然として必須であることがわかりました。したがって、最も簡単な方法は、ユーザーに再度ログインを強制し、ログイン中にSpringに役割の割り当てを処理させることです。
Spring Securityでユーザーの認証を解除するには、以下を呼び出す必要があります。
SecurityContextHolder.clearContext();
別の方法として、UserDetailsService実装で例外をスローできます(以下を参照)。ユーザーの認証を解除し、ユーザーコンテキストデータを失うという欠点があるため、新しいローカルアカウントを作成するプロセス中に、新しいユーザーアカウントをopenidアカウントと照合することは不可能です。また、ユーザーログイン後、これらのアカウントを従来のユーザー名とパスワードと一致させる必要があります。私の解決策は、新しいアカウントを作成した直後にユーザーの認証を解除することでした。
ユーザーの役割(特権)を付与するには、UserDetailsServiceをオーバーライドする必要があります。誰かがこれが便利だと思った場合に備えて、これが私の実装です。
public final class MyUserDetailsService implements UserDetailsService {
private final UsersDao usersDao;
@Autowired
public UserDetailsServiceImpl(final UsersDao usersDao) {
this.usersDao = usersDao;
}
@Override
public UserDetails loadUserByUsername(final String username) {
UserEntity user = usersDao.getUserByOpenIdIdentifier(username);
if (user == null) {
// there is no such user in our db, we could here throw
// an Exception instead then the user would also be deuthenticated
return new User(username, "", new ArrayList<GrantedAuthority>());
}
//here we are granting to users roles based on values from db
final Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new SimpleGrantedAuthority(user.getUserType().toString()));
final UserDetails result = new User(username, "", authorities);
return result;
}
}