У меня есть следующая проблема, когда пользователь входит в систему успешно, но постоянно выполняет серию перенаправлений, пока браузер не покажет: «Страница не перенаправляется должным образом».
Я настроил свой проект после этого Baeldung, используя Spring Security 5 - Сервер авторизации: https://github.com/Baeldung/spring-security-oauth/tree/master/oauth-авторизация-сервер
Цикл перенаправления выглядит следующим образом:
Никакие другие ошибки или информация не отображаются в журналах.
Через серию исключений я понял, что проблема может заключаться в моей реализации службы сведений о пользователях, потому что, если я устраню ее и установлю Baeldung, если она сработает. Вот моя реализация:
@Service
public class SimpleUserDetailsService implements UserDetailsService {
private final SimpleUserRepository userRepository;
public SimpleUserDetailsService(SimpleUserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Optional<SimpleUser> userOpt = userRepository.findByUsername(username);
SimpleUserDetails details = userOpt.map(user -> {
Collection<GrantedAuthority> authorities = getAuthorities(user.getRoles());
String repoUsername = user.getUsername();
String password = user.getPassword();
boolean enabled = user.isEnabled();
return new SimpleUserDetails(repoUsername, password, enabled, true, true, true, authorities, user.getId());
}).orElseThrow();
return details;
}
private Collection<GrantedAuthority> getAuthorities(List<SimpleRole> roles) {
Collection<GrantedAuthority> simpleAuthorities = roles.stream()
.map(a -> new SimpleGrantedAuthority(getAuthorityFor(a.getRole()))).collect(Collectors.toList());
return simpleAuthorities;
}
private String getAuthorityFor(String role) {
return "history.read";
}
}
Мой Config
файл:
@Bean
public CommandLineRunner demo(SimpleUserRepository repository) {
return (args) -> {
PasswordEncoder encoder = passwordEncoder();
SimpleUser john = new SimpleUser("john", encoder.encode("pass"), true, "[email protected]");
SimpleUser admin = new SimpleUser("admin", encoder.encode("123"), true, "[email protected]");
SimpleUser dan = new SimpleUser("dan", encoder.encode("123"), true, "[email protected]");
SimpleRole johnRole = new SimpleRole(john, SimpleRole.ADMIN);
SimpleRole johnRole2 = new SimpleRole(john, SimpleRole.USER);
SimpleRole adminRole = new SimpleRole(admin, SimpleRole.ADMIN);
SimpleRole danRole = new SimpleRole(dan, SimpleRole.ADMIN);
john.setRoles(Arrays.asList(johnRole, johnRole2));
admin.setRoles(List.of(adminRole));
dan.setRoles(List.of(danRole));
repository.save(john);
repository.save(admin);
repository.save(dan);
};
}
@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
@Bean
public AuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setUserDetailsService(userDetailsService);
daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
return daoAuthenticationProvider;
}
@Bean
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
http.authorizeRequests(authorizeRequests ->
authorizeRequests.anyRequest().authenticated()
)
.formLogin(withDefaults());
**http.authenticationProvider(authenticationProvider());**
return http.build();
}
Если я удалю вышеупомянутый код с помощью:
@Bean
UserDetailsService users() {
UserDetails user = User.withDefaultPasswordEncoder()
.username("admin")
.password("password")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
то приложение нормально перенаправляет на нужную ссылку.
Что я пробовал:
AuthenticationProvider
, несмотря на то, что DaoAuthenticationProvider
прошла правильную аутентификацию, очевидно, не сработалоПроблема заключалась в кодировщике паролей, я не уверен, что это ошибка, но после замены моего кодировщика паролей следующим он не работает.
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
По умолчанию кодировщиком паролей является BCrypt, но использование конкретной реализации BCrypt также приведет к такому же ошибочному поведению, как описано в исходном посте, поэтому вам нужно использовать именно эту реализацию.