До сих пор я хранил свое имя пользователя и зашифрованные пароли в базе данных.
Мой пользовательский UserDetailsService ищет пользователя в базе данных. Пароли хранятся в зашифрованном виде, поэтому здесь применяется BCryptPasswordEncoder.
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
}
Проблема: теперь мне нужно добавить дополнительный источник аутентификации, который обслуживает пароли незашифрованный (я не могу это контролировать). Таким образом, если аутентифицированный пользователь не может быть найден в моей базе данных, я хочу проверить дополнительный источник с незашифрованными паролями. Но как я могу отключить кодировщик BCrypt для этих случаев?
@chrylis, так что мне пришлось бы ставить перед всеми моими закодированными паролями в базе данных префикс {bcrypt}, это правильно? А потом просто полагаться на весенние значения по умолчанию?
Пароли Bcrypt уже имеют префикс $2a$.
Я попробовал это, не устанавливая свой собственный кодировщик паролей, поэтому загружается DelegatingPasswordEncoder по умолчанию: префикс с {bcrypt} работает и делегирует кодировщику brcypt. Простое использование простого закодированного pw, начинающегося с $2a$, не работает! Может я что-то не так делаю?
Я удивлен и не совсем уверен, что происходит, но если это сработает для вас, отлично!




несколько дней назад я также столкнулся с этой проблемой, мои устаревшие системные данные зашифрованы в MD5, но новый пароль для сохранения системы в BCrypt
для решения этой проблемы я пишу некоторый собственный код и использую AuthenticationProvider вместо UserDetailsService
здесь я вырезаю свой код для вашей помощи
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Autowired
LoginDao loginDao;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(12);
}
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
List<GrantedAuthority> grantList = new ArrayList<>();
String name = authentication.getName();
String password = ((String) authentication.getCredentials()).trim();
try {
UserModel user = loginDao.getUser(name);
if (user != null) {
if (passwordEncoder().matches(password, user.getLoginPass())) {
// System.out.println("------Good new & Strong password -----");
GrantedAuthority authority = new SimpleGrantedAuthority(user.getAuthotype().toString());
grantList.add(authority);
}else if (password.equals(user.getLoginPass())) {//here i have md5 checker service , i remove it for your help
// System.out.println("------old password! should be change it-----");
GrantedAuthority authority = new SimpleGrantedAuthority(user.getAuthotype().toString());
grantList.add(authority);
}else {
throw new BadCredentialsException("Please enter a valid username and password.");
}
return new UsernamePasswordAuthenticationToken(user, password, grantList);
}
} catch (Exception e) {
e.printStackTrace();
throw new BadCredentialsException("Please enter a valid username and password.");
}
throw new BadCredentialsException("Please enter a valid username and password.");
}
@Override
public boolean supports(Class<? extends Object> authentication) {
return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
}
}
и измените свой код класса SecurityConfiguration
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider);
}
Согласно текущим документам (https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/crypto/password/DelegatingPasswordEncoder.html),
Мне просто нужно удалить мой установщик .passwordEncoder(), чтобы весной полагаться на новую функцию делегирования пароля по умолчанию.
Затем добавьте ко всем моим паролям префикс {bcrypt} для моих паролей к базе данных и {noop} для моих новых паролей в виде открытого текста.
Вы можете настроить несколько поставщиков аутентификации, как показано ниже. Каждый провайдер аутентификации тестируется по порядку, и тот, который прошел проверку первым, предоставляет аутентифицированные данные, а остальные пропускаются. Подобный вариант использования реализован аналогичным образом, когда вы должны сначала пройти аутентификацию через базу данных, а затем сервер LDAP (или наоборот) также обрабатывается аналогичным образом.
@Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProviderWithEncryptedUser);
auth.authenticationProvider(authenticationProviderWithNonEncryptedUser);
}
Это замечательно. Я объединил этот подход, используя два DaoAuthenticationProvider, у каждого из которых есть свой UserDetailsService. Принимая во внимание, что один — мой старый сервис bcrypt, а другой — новый незашифрованный сервис.
В данный момент я не на своей машине разработки, но я считаю, что есть составной кодировщик паролей специально для этого варианта использования (онлайн-миграция). Вы можете распознать пароли Bcrypt по префиксу.