52 votes

Authentification personnalisée de Spring Security et codage du mot de passe

Est-il un tuto ou quelqu'un aurait-il des pointeurs sur comment effectuer les opérations suivantes avec Ressort de Sécurité?

Tâche:

J'ai besoin d'obtenir le sel de ma base de données pour l'authentification nom d'utilisateur et de l'utiliser pour crypter le mot de passe fourni (à partir de la page de connexion) pour le comparer à la stockées mot de passe crypté (un.k.un. authentifier l'utilisateur).

informations supplémentaires:

J'utilise une base de données personnalisée de la structure. Un UserDetails objet est créé par une coutume UserDetailsService qui à son tour utilise un custom DAOProvider pour obtenir des informations de la base de données.

mon security.xml le fichier:

<authentication-manager>
    <authentication-provider user-service-ref="userDetailsService">
    </authentication-provider>
</authentication-manager>

maintenant, je suppose que je vais avoir besoin de

        <password-encoder hash="sha" />

mais quoi d'autre? Comment dois-je dire à spring security pour utiliser le databaseprovided sel pour encoder le mot de passe?


edit:

J'ai trouvé Cette SORTE de poste à informatative mais pas suffisante: Si je définir un sel source de mon xml pour être utilisé par le mot de passe de l'encodeur, comme suit:

        <password-encoder ref="passwordEncoder">                
            <salt-source ref="saltSource"/>
        </password-encoder>

Je vais avoir à écrire une coutume SaltSource à utiliser mon custom de sel. Mais ce n'est pas pour être trouvé à l'intérieur de l' UserDetails objet. Alors...

Solution 1:

Puis-je utiliser une Implémentation personnalisée de UserDetails qui pourrait alors être le sel de la propriété?

<beans:bean id="saltSource" class="path.to.MySaltSource"
    p:userPropertyToUse="salt"/>

et

@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
}

personnalisé de l'Utilisateur de la Classe:

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"/>


Variante 2:

Sinon, je serais obligé d'injecter mon accountDAO dans l' SaltSource pour en extraire le sel pour un userName de la base de données.

MAIS: Comment ne Ressort d'appel de Sécurité de l' SaltSource? Toujours avec saltSource.getSalt(userDetails)?

Alors j'avais juste à faire en sorte que mes SaltSource utilise userDetails.accountName sur mon accountDAO pour récupérer le sel.


Edit2:

Viens d'apprendre que mon approche est.. héritage.. :( Donc je suppose que je vais juste utiliser le StandardPasswordEncoder (ce qui me reste à comprendre comment l'utiliser exactement).

BTW: j'ai mis en place la première option avec une coutume UserDetails classe étendant la classe d'Utilisateur et simplement l'ajout d'un sel de propriété dont une ensuite être transmise à la SaltSource comme un userPropertyToUse comme il a été proposé dans le post mentionné dans Edition 1...


EDIT 3:

Je viens de la StandardPasswordEncoder de travail, donc je vais le laisser quelques conseils ici:

Utiliser le StandardPasswordEncoder pour l'Authentification:

<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>

Cela nécessite le printemps-sécurité-module crypto dans la version 3.1.0.RC? autant que je sache. Ne pouvais pas trouver un référentiel qui a un 3.0. version (même si quelque part, il avait les versions répertoriées inclus 3.0.6 et ainsi de suite). Aussi les documentations parle de printemps de sécurité 3.1 alors je me suis dit, je vais juste aller avec qui.

Lors de la création d'un utilisateur (pour moi seul un admin peut le faire), je viens d'utiliser

        StandardPasswordEncoder encoder = new StandardPasswordEncoder();
        String result = encoder.encode(password);

et je suis fait.

Printemps de sécurité, de façon aléatoire, de créer un sel et de l'ajouter à la chaîne de mot de passe avant de les stocker dans la base de données, donc pas de sel de la colonne est plus nécessaire.

On peut cependant également fournir un mondial du sel comme un argument du constructeur (new StandardPasswordEncoder("12345");), mais je ne sais pas comment configurer mon configuration de la sécurité afin de récupérer cette valeur à partir d'une fève au lieu de fournir une chaîne statique avec <constructor-arg name="secret" value "12345" />. Mais je ne sais pas combien cela est nécessaire, de toute façon.

34voto

Pete Points 2782

Je note ceci comme une réponse, car j'ai résolu mon problème et aucun autre commentaire ou réponse n'a été donné:

Edit 1 - Alternative 1 répond à la question d'origine

MAIS je devais apprendre que le salage personnalisé par mot de passe est une approche héritée qui n’est plus nécessaire dans Spring Security 3.1, comme je le décris dans

Modifier 3 où j'ai laissé quelques indications sur la façon d'utiliser le StandardPasswordEncoder pour les sels automatisés qui sont stockés avec le mot de passe.

4voto

rooftop Points 2128

Pour ce que ça vaut, j'ai écrit ce billet de blog détaillant ce que vous avez décrit: http://rtimothy.tumblr.com/post/26527448708/spring-3-1-security-and-salting-passwords

0voto

user1447450 Points 31

Pour récupérer le sel global d'un haricot, utilisez le langage Spring Expression Language ou SpEL.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X