Bonjour,
Je gère une application qui utilise LDAP et Acegi pour effectuer l'authentification des utilisateurs. Pour s'authentifier, l'utilisateur, en plus de son login et mot de passe) doit saisir l'organisme auquel il appartient.
J’ai donc un formulaire de login qui se compose de 3 champs input :
- login (name html = j_username)
- password (name html = j_password)
- organisme (name html = j_organism)
Ce formulaire renvoie vers une url logique /j_acegi_security_check (jusque la, tout va bien…)
Cette URL logique est interceptée par acegi pour l’authentification. Un filtre est alors appliqué (AuthenticationProcessingFilter appliqué sur le /j_acegi_security_check )... Voici la desciption spring du bean :
1 2 3 4 5 6 7
| <bean id="authenticationProcessingFilter" class="fr.fmp.multimut.habilitations.acegi.MultimutAuthenticationProcessingFilter" >
<property name="authenticationManager" ref="authenticationManager" />
<property name="authenticationFailureUrl" value="/sl10dgw.nav?error=1" />
<property name="defaultTargetUrl" value="/veriflogin.nav" />
<property name="filterProcessesUrl" value="/j_acegi_security_check" />
<property name="alwaysUseDefaultTargetUrl"><value>true</value></property>
</bean> |
Ce filtre définit ce qu’il faut utiliser pour l’authentification (c’est l’authenticationManager), l’URL de redirection en cas d’écher, l’URL de redirection en cas de succès, quelle URL intercepter pour effectuer l’action d’authentification.
L’authenticationManager utilise d’autres classes pour effectuer l’authentification de l’utilisateur selon les données saisies dans le formulaire. Parmi celles-ci, il y a une classe qui est chargée d’effectuer une recherche dans l’annuaire. Voici sa définition :
1 2 3 4 5 6
| <bean id="ldapUserSearch" class="org.acegisecurity.ldap.search.FilterBasedLdapUserSearch">
<constructor-arg index="0" value="" />
<constructor-arg index="1" value="(${ldap.nomAttribut.login}={0})" />
<constructor-arg index="2" ref="initialContextFactory" />
<property name="searchSubtree" value="true" />
</bean> |
Pour le moment, je ne me suis pas occupée de l’organisme saisi au login.
La base de la recherche (premier argument du constructeur) est donc la racine de l’annuaire.
Le login (second argument du constructeur – enfin cet argument représente le filtre de recherche) est récupéré dans le formulaire… Il est passé de la manière suivante : {0}… Et c’est la que commence mon problème…
Le mot de passe quant à lui est récupéré je ne sais pas comment pas acegi…
Le hic, c’est qu’en plus du login et du mot de passe, j’ai besoin de connaitre l’organisme pour rechercher l’utilisateur.
En fait mes utilisateurs appartiennent à des organismes… Et deux utilisateurs appartenant à 2 organismes différents peuvent avoir le même login…
Il faut donc que la base de ma recherche se limite à la branche de l’annuaire concernant l’organisme saisi dans le formulaire... Pour cela, il faudrait que le premier argument de mon constructeur soit quelque chose comme « ou=OrganismeDuFormulaire ».
J’ai bien sûre essayé
<constructor-arg index="0" value="ou={1}"/> et <constructor-arg index="0" value="ou={2}"/>
au cas où {1} ou {2} serait remplacé par le j_organism…
Mais non !
D’ailleurs je n’ai toujours pas compris comment le {0} pouvait être remplacé par le login du formulaire. C’est pour ca que j’ai essayé les deux solutions précédentes !
Donc si quelqu’un sait comment fonctionne le remplacement du {0} par le login… Déjà j’aurai compris quelque chose, ca m’aidera surement !
Et encore mieux, si quelqu’un à une idée pour passer mon organisme à ce foutu constructeur… 
Petite remarque… Même si j’essaie de passer {0} pour l’organisme… Ca n’est pas interprété ! La je ne comprends vraiment pas… Qui interprète ca truc… ? Spring, ageci… ?
En mettant ceci…
<constructor-arg index="0" value="(${ldap.nomAttribut.organisme}={0})" />
J’obtiens l’erreur suivante :
Authentication request failed: org.acegisecurity.AuthenticationServiceException: LdapCallback;(ou={0}): [LDAP: error code 34 - invalid DN]; nested exception is javax.naming.InvalidNameException: (ou={0}): [LDAP: error code 34 - invalid DN]; remaining name '(ou={0})'; nested exception is org.acegisecurity.ldap.LdapDataAccessException: LdapCallback;(ou={0}): [LDAP: error code 34 - invalid DN]; nested exception is javax.naming.InvalidNameException: (ou={0}): [LDAP: error code 34 - invalid DN]; remaining name '(ou={0})'
Du coup je me suis dit, ben en fait je vais essayer de passer l’organisme dans le filtre directement (argument d’indice 1 du constructeur)…
Le filtre étant de la forme (& (ou=organisme)(uid=login)).
Ce qui donne dans mon fichier :
<constructor-arg index="1" value="(&(${ldap.nomAttribut.organisme}={1})(${ldap.nomAttribut.login}={0}))" />
Et la… c’est le drame…
2 soucis… Déjà je ne peux pas mettre le & dans la value… -> Erreur de construction du bean…
Je l’ai donc enlevé pour voir, même si mon filtre est inexact, si j’arrive à récupérer mon organisme… Et bien non… Voici l’erreur :
Authentication request failed: org.acegisecurity.AuthenticationServiceException: LdapCallback;number exceeds argument list: 1; nested exception is javax.naming.directory.InvalidSearchFilterException: number exceeds argument list: 1; remaining name ''; nested exception is org.acegisecurity.ldap.LdapDataAccessException: LdapCallback;number exceeds argument list: 1; nested exception is javax.naming.directory.InvalidSearchFilterException: number exceeds argument list: 1; remaining name ''
C’est donc une histoire de liste récupérée / initialisée je ne sais comment … Ahhhhhhhhhhh !
{0} est donc le premier élément d’une liste qui ne contient qu’un seul élément (qui est le j_username de mon formulaire) !
Merci d'avance !!!
Partager