Есть ли там учебник или у кого есть указатели на то, как сделать следующее с помощью Spring -Security?
Задача:
Мне нужно получить соль из моей базы данных для аутентификации имени пользователя и использовать ее для шифрования предоставленного пароля (со страницы входа), чтобы сравнить его с сохраненным зашифрованным паролем (a.k.a. аутентифицировать пользователя).
дополнительная информация:
Я использую настраиваемую структуру базы данных. Объект UserDetails
создается через пользовательский UserDetailsService
, который, в свою очередь, использует пользовательский DAOProvider для получения информации из базы данных.
my security.xml
:
<authentication-manager>
<authentication-provider user-service-ref="userDetailsService">
</authentication-provider>
</authentication-manager>
теперь я думаю, мне нужно
<password-encoder hash="sha" />
но что еще? Как сообщить spring безопасности использовать базу данных, полученную солью, чтобы закодировать пароль?
изменить
Я нашел Это сообщение SO, чтобы быть информативным, но не достаточным: если я определяю источник солей в моем xml, который будет использоваться кодеком паролей, вот так:
<password-encoder ref="passwordEncoder">
<salt-source ref="saltSource"/>
</password-encoder>
Мне нужно написать собственный SaltSource для использования моей солидной соли. Но это не должно быть найдено внутри объекта UserDetails
. Так что...
Альтернатива 1:
Можно ли использовать пользовательскую реализацию UserDetails, которая может иметь свойство salt?
<beans:bean id="saltSource" class="path.to.MySaltSource"
p:userPropertyToUse="salt"/>
и
@Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException, DataAccessException {
// ...
return buildUserFromAccount(account);
}
@Transactional(readOnly = true)
UserDetailsImpl buildUserFromAccount(Account account){
// ... build User object that contains salt property
}
пользовательский класс пользователя:
public class UserDetailsImpl extends User{
// ...
private String salt;
public String getSalt() { return salt; }
public void setSalt(String salt) { this.salt = salt; }
}
security.xml:
<authentication-manager>
<authentication-provider user-service-ref="userDetailsService">
<password-encoder hash="sha">
<salt-source ref="saltSource"/>
</password-encoder>
</authentication-provider>
</authentication-manager>
<beans:bean id="saltSource" class="org.springframework.security.authentication.dao.ReflectionSaltSource" p:userPropertyToUse="salt"/>
Альтернатива 2:
В противном случае мне пришлось бы ввести мою учетную записьDAO в SaltSource
, чтобы извлечь соль для заданного userName
из базы данных.
НО: Как spring Безопасность вызывает SaltSource
? Всегда с saltSource.getSalt(userDetails)
?
Тогда мне просто нужно убедиться, что мой SaltSource
использует userDetails.accountName
на моем accountDAO
для извлечения соли.
Edit2:
Только что узнал, что мой подход... legacy..:( Так что, я думаю, я просто использую StandardPasswordEncoder
(который мне еще нужно выяснить, как использовать именно).
BTW: я применил первый вариант с пользовательским классом UserDetails, расширяющим класс User, и просто добавив свойство salt, которое затем передается в SaltSource как userPropertyToUse, как и было предложено в сообщении SO, упомянутом в Edit 1...
ИЗМЕНИТЬ 3:
Просто получил работу StandardPasswordEncoder, поэтому я оставлю несколько указателей здесь:
Используйте StandardPasswordEncoder для аутентификации:
<beans:bean id="encoder"
class="org.springframework.security.crypto.password.StandardPasswordEncoder">
</beans:bean>
<authentication-manager>
<authentication-provider user-service-ref="userDetailsService">
<password-encoder ref="encoder" />
</authentication-provider>
</authentication-manager>
Для этого требуется модуль Spring -security-crypto в версии 3.1.0.RC? насколько я знаю. Не удалось найти репозиторий с 3.0. версии (хотя где-то у него были версии, включенные в 3.0.6 и т.д.). Также в документах рассказывается о spring безопасности 3.1, поэтому я подумал, что я просто пойду с этим.
При создании пользователя (для меня это может сделать только администратор), я просто использую
StandardPasswordEncoder encoder = new StandardPasswordEncoder();
String result = encoder.encode(password);
и я закончил.
Spring безопасность будет беспорядочно создавать соль и добавлять ее в строку пароля, прежде чем хранить ее в базе данных, поэтому не нужен столбец солей.
Однако можно также предоставить глобальную соль в качестве аргумента конструктора (new StandardPasswordEncoder("12345");
), но я не знал, как настроить мою конфигурацию безопасности, чтобы получить это значение из bean вместо того, чтобы поставлять статическую строку с <constructor-arg name="secret" value "12345" />
. Но я не знаю, сколько это необходимо в любом случае.