[Spring Security] Authentification LDAP + autorisations BDD

Ce besoin est assez courant dans le développement d'applications : les utilisateurs sont présents dans un annuaire général, et c'est à chaque application de gérer ses droits d'accès.
La documentation de Spring Security explique bien le fonctionnement général du framework, mais décrit principalement les cas nominaux que sont le "tout LDAP" et le "tout BDD".
Je vais montrer ici les quelques points de configuration nécessaires afin de mélanger ces deux aspects.

Pré-requis :
- Spring security
- Spring ldap

Je vais commencer par présenter les différentes briques qui vont nous servir à faire fonctionner le tout.

Tout d'abord, nous allons définir la connexion à notre annuaire :

<bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
	<constructor-arg index="0" value="ldap.example.com:389/dc=netapsys,dc=com" />
	<!--<property name="userDn" value="cn=manager,dc=netapsys,dc=com" />-->
	<!--<property name="password" value="password" />-->
</bean>

Ici, nous utilisons une connexion anonyme à l'annuaire, si une athentification est nécessaire, il suffit de décommenter les deux lignes.

Ensuite nous allons définir un objet capable de faire la recherche dans l'annuaire :

<bean id="ldapUserSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
	<constructor-arg index="0" value="ou=personnes" /> <!-- Branche principale à partir de laquelle faire la recherche -->
	<constructor-arg index="1" value="(uid={0})" /> <!-- Critère de recherche LDAP, ici le login de l'utilisateur correspond à l'uid de l'entrée LDAP -->
	<constructor-arg index="2" ref="contextSource" />
	<property name="searchSubtree" value="true" /> <!-- Recherche dans les sous-branches -->
</bean>

Enfin, nous allons définir notre propre classe de gestion des droits :

<bean id="netapsysAuthoritiesPopulator" class="com.netapsys.security.NetapsysAuthoritiesPopulator" />

Petit artifice, bien que cette classe ait pour but de récupérer les autorisations en base de données, elle doit étendre la classe LdapAuthoritiesPopulator du framework. Notons qu'arrivés à ce stade, nous sommes sûrs que l'utilisateur est authentifié.

/** Classe permettant de récupérer les droits d'un utilisateur se connectant à l'application.<br />
 * Si le login n'existe pas en base, alors l'utilisateur a par défaut les droits d'un invité. */
public class NetapsysAuthoritiesPopulator implements LdapAuthoritiesPopulator
{
    /** Service des utilisateurs. */
    @Resource(name = "utilisateurService") private UtilisateurService utilisateurService;

    /** {@inheritDoc} */
    @Override public Collection<GrantedAuthority> getGrantedAuthorities(final DirContextOperations userData, final String username) {
        final List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        final Utilisateur user = this.utilisateurService.getByLogin(username);	// Recherche de l'utilisateur en base
        if (user == null) {
            authorities.add(new GrantedAuthorityImpl("ROLE_GUEST"));
        } else {
            authorities.add(new GrantedAuthorityImpl(user.getProfil().getRole()));
        }
        return authorities;
    }

    /** Setter pour utilisateurService.
     * @param utilisateurService le utilisateurService à écrire. */
    public void setUtilisateurService(final UtilisateurService utilisateurService) {
        this.utilisateurService = utilisateurService;
    }
}

Assemblons maintenant toutes ces parties :

<bean id="ldapAuthProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
	<constructor-arg index="0">
		<bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
			<constructor-arg index="0" ref="contextSource" />
			<property name="userSearch" ref="ldapUserSearch" />
		</bean>
	</constructor-arg>
	<constructor-arg index="1">
		<bean ref="netapsysAuthoritiesPopulator" />
	</constructor-arg>
</bean>

Nous n'avons plus qu'à injecter ce provider au gestionnaire de sécurité de notre application :

<security:authentication-manager>
	<security:authentication-provider ref="ldapAuthProvider" />
</security:authentication-manager>

Et le tour est joué !

Vous trouverez en pièce jointe un fichier de configuration Spring d'exemple.

Un commentaire

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.