Ok, więc oddzielenie uwierzytelniania od autoryzacji, jak wspomniano w poście Samuela, było naprawdę pomocne. Jednak nadal istnieje wiele błędów i uważam, że deautentyfikacja jest koniecznością, ponieważ na wiosnę nie ma łatwego sposobu dodawania nowych ról. Najłatwiej jest więc zmusić użytkownika do ponownego zalogowania się i pozwolić wiosłującemu na przypisanie roli podczas logowania.
W celu deauthenticate użytkownik w wiosennej bezpieczeństwa trzeba powołać:
SecurityContextHolder.clearContext();
jako alternatywę można rzucić wyjątek w implementacji UserDetailsService (patrz niżej). Ma wadę, że można deauthenticate użytkownika i stracić dane kontekstu użytkownika, więc byłoby niemożliwe, aby dopasować nowy użytkownik accout z kontem openid podczas tworzenia nowego konta lokalnego. I musisz połączyć te konta po zalogowaniu użytkownika z tradycyjną nazwą użytkownika i hasłem. Moim rozwiązaniem było deauthenticate użytkownika tuż po utworzeniu nowego konta.
W celu przyznania ról użytkowników (przywileje) trzeba zastąpić UserDetailsService w przypadku kogoś znaleźć to przydatny tutaj jest moje wykonanie:
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;
}
}