В настоящее время я пытаюсь изучить безопасность Spring. Я использовал BCryptPasswordEncoder для кодирования пароля пользователя перед сохранением в базе данных
Код:
@Override
public void saveUser(User user) {
user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
user.setActive(1);
Role userRole = roleRepository.findByRole("ADMIN");
user.setRoles(new HashSet<Role>(Arrays.asList(userRole)));
userRepository.save(user);
}
Затем использовал его во время аутентификации, и пользователь прошел аутентификацию, как ожидалось.
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.
jdbcAuthentication()
.usersByUsernameQuery(usersQuery)
.authoritiesByUsernameQuery(rolesQuery)
.dataSource(dataSource).passwordEncoder(bCryptPasswordEncoder);
}
Затем я удалил .passwordEncoder(bCryptPasswordEncoder); из метода configure(), но пользователи с закодированным паролем успешно проходят аутентификацию.
Затем я удалил кодировщик паролей как из метода saveUser(), так и из метода configure() и сохранил User в базе данных (т.е. без кодирования пароля) и попытался получить доступ к аутентифицированной странице, но у меня есть AccessedDeniedException,
, но пользователи с закодированным паролем все равно проходят аутентификацию, хотя удалил passwordEncoder() из метода configure(). Почему это происходит?
Использует ли Spring Security по умолчанию кодировщик паролей во время аутентификации?
Если да, то как использовать Spring Security без кодирования пароля?
@ efex09 да, и он отлично работает с закодированным паролем, но аутентификация не работает, если я не использую кодировку пароля
Почему мой вопрос отклонен?
К сожалению, многие отрицательные голоса не удосуживаются объяснять, почему они считают вопрос плохим. Возможно, мы никогда не узнаем.
Удалить закодированный пароль из базы данных. Удалите bean-компонент BCryptPasswordEncoder. Сохранять пользователя без кодирования пароля. Затем попробуйте аутентифицировать пользователя, пароль которого не закодирован.
@ efex09 У меня есть объекты User с закодированными паролями и простыми паролями в базе данных .. и пользователи с закодированными паролями успешно проходят аутентификацию, а пользователи с обычным паролем не работают, даже если в методе configure() не используется кодировщик паролей.
Это зависит от того, какую версию Spring Security вы используете. В старых версиях не используется кодировщик паролей по умолчанию, в более новых версиях используется по соображениям безопасности.
@ M.Deinum Я использую Spring Security 5.0.6
Что по умолчанию включено. На самом деле у него даже лучшая схема безопасности, так как вы можете указать в своем пароле, какую кодировку использовать (и, как мне кажется, по умолчанию используется Bcrypt). Поэтому, если у вас есть простой пароль, используйте префикс {noop}<the-password>, и он будет использовать простой кодировщик. Используйте {bcrypt} в качестве префикса для crypt (который также используется по умолчанию). См. docs.spring.io/spring-security/site/docs/current/reference/…
@ M.Deinum Спасибо, теперь это работает.




В Spring Security 5 шифрование паролей всегда включено. По умолчанию используется шифрование bcrypt. Что приятно в Spring Security 5, так это то, что он позволяет вам указать в пароле, какое шифрование использовалось для создания файла has.
Для этого см. Формат хранения паролей в Справочном руководстве по безопасности Spring. Короче говоря, это позволяет вам ставить перед паролем хорошо известный ключ к алгоритму. Формат хранения - {<encryption>}<your-password-hash>.
Если ничего не использовать, он превратится в {noop}your-password (который будет использовать NoOpPasswordEncoder, а {bcrypt}$a2...... будет использовать BcryptPasswordEncoder. Есть несколько алгоритмов, поддерживаемых из коробки, но вы также можете определить свой собственный.
Чтобы определить свой собственный, создайте свой собственный PasswordEncoder и зарегистрируйте его под ключом с помощью DelegatingPasswordEncoder.
Не могли бы вы заменить «encrypt» на «hash» или «encode» или что-то в этом роде? Это не шифрование.
@M. Deinum В моем приложении администратор должен войти в учетную запись пользователя, а у администратора есть закодированный пароль. Итак, есть ли способ для администратора обойти эту кодировку пароля при входе в систему ??? Пожалуйста, помогите мне. Т.е. в моем приложении есть два способа входа один - пользователем, который обычно происходит с помощью открытого текстового пароля, который использует кодировку пароля при весенней загрузке, а другой - администратором, где хешированный пароль используется администратором и который должен обходить кодировку пароля весенней загрузки. Я использую BCryptEncoder.
Возможно, вы сможете реализовать этот простой код, чтобы избежать Spring Encoder
public class PasswordEnconderTest implements PasswordEncoder {
@Override
public String encode(CharSequence charSequence) {
return charSequence.toString();
}
@Override
public boolean matches(CharSequence charSequence, String s) {
return charSequence.toString().equals(s);
}
}
и добавьте в свой WebSecurityConfig:
@Bean
public PasswordEncoder passwordEncoder(){
return new PasswordEnconderTest();
}
это не рекомендуется, но вы можете реализовать
Не уверен, что это то, что вам нужно, но я использовал небольшое дешевое обходное решение, поэтому мне не нужно было беспокоиться о кодировании моей базы данных.
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
DataSource dataSource;
@Autowired
public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource)
.usersByUsernameQuery("select username,CONCAT('{noop}',password),true from
public.\"Users\" where username=?")
.authoritiesByUsernameQuery("select username,role from public.\"Users\" where
username=?");
}
...
Обратите внимание, вместо того, чтобы получать пароль, я сначала объединяю его с {noop}, чтобы система не использовала кодировку.
Наверное грех но пока работает.
Ты пробовал
@Bean
public static NoOpPasswordEncoder passwordEncoder() {
return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
}
А затем в настройке глобальной безопасности
@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().usersByUsernameQuery(usersQuery).dataSource(dataSource)
.authoritiesByUsernameQuery(rolesQuery).passwordEncoder(passwordEncoder());
}
Вы создали bean-компонент BCryptPasswordEncoder?