Подтвердить что ты не робот

Spring Безопасность Индивидуальная проверка подлинности и кодирование пароля

Есть ли там учебник или у кого есть указатели на то, как сделать следующее с помощью 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" />. Но я не знаю, сколько это необходимо в любом случае.

4b9b3361

Ответ 1

Я отмечу это как ответ, так как я решил свою проблему, и никаких других комментариев или ответов не было дано:

Изменить 1 - Альтернатива 1 отвечает на исходный вопрос

НО Мне пришлось узнать, что настроенный пароль - это устаревший подход, который больше не нужен в Spring Security 3.1, как я описал в

Изменить 3, где я оставил несколько указателей на использование StandardPasswordEncoder для автоматизированных солей, которые хранятся с паролем.

Ответ 3

Чтобы извлечь глобальную соль из bean, используйте язык выражения Spring или SpEL.

<beans:bean id="encoder" 
        class="org.springframework.security.crypto.password.StandardPasswordEncoder">
    <constructor-arg value="#{someotherBean.somePropertyWithAGetterMethod"/>
</beans:bean>