Мне не ясно, как приклеить мой CustomPasswordEncoder к процессу аутентификации при весенней загрузке. В конфигурации я определяю, что при весенней загрузке должен использоваться мой CustomAuthenticationProvider с моим UserDetailsService и моим CustomPasswordEncoder
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Autowired
private CustomAuthenticationProvider customAuthenticationProvider;
@Autowired
protected void configureGlobal(AuthenticationManagerBuilder builder) throws Exception {
builder.authenticationProvider(customAuthenticationProvider)
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder(){
PasswordEncoder encoder = new CustomPasswordEncoder();
return encoder;
}
}
Мой CustomPasswordEncoder будет кодировать в значение md5 (я знаю, что это небезопасно, но это устаревшая база данных)
@Component
public class CustomPasswordEncoder implements PasswordEncoder{
@Override
public String encode(CharSequence rawPassword) {
return DigestUtils.md5DigestAsHex(rawPassword.toString().getBytes());
}
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
return rawPassword.toString().equals(encodedPassword);
}
}
В CustomAuthtenticationProvider будет выполнена проверка подлинности. Поставленный пароль будет закодирован с помощью passwordEncoder.encode (). Пользователь будет извлечен из базы данных, затем я снова использую passwordEncoder для сопоставления. Если совпадение прошло успешно, будет создан объект аутентификации.
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Autowired
private UserServiceImpl userService;
@Autowired
private CustomPasswordEncoder passwordEncoder;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
System.out.println("authentication = [" + authentication + "]");
String name = authentication.getName();
Object credentials = authentication.getCredentials();
String password = credentials.toString();
//why is this necessary isnt it called automatically?
String passwordEncoded = passwordEncoder.encode((CharSequence) credentials);
Optional<UserEntity> userOptional = userService.findByUsername(name);
if (userOptional.isPresent() && passwordEncoder.matches(passwordEncoded, userOptional.get().getPassword())) {
List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
grantedAuthorities.add(new SimpleGrantedAuthority(userOptional.get().getRoles().toString()));
Authentication auth = new
UsernamePasswordAuthenticationToken(name, password, grantedAuthorities);
return auth;
}
else{
throw new BadCredentialsException("Authentication failed for " + name);
}
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
Это правильный подход? Я думал, что CustomPasswordEncoder будет использоваться «автоматически» или только в том случае, если вы используете один из предоставленных провайдеров аутентификации, таких как jdbcAuthenticationProvider. Может быть, кто-то может объяснить порядок событий процесса аутентификации. Я провел некоторое исследование в сети, но все еще не могу понять это подробно.