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.