Projet

Général

Profil

Scénario #31512

Mis à jour par Daniel Dehennin il y a plus de 3 ans

{{>toc}}

h3. Problème

Sur Scribe, nous avons deux sources de données qui ne peuvent pas être utilisées ensemble simplement :

* L’annuaire OpenLDAP contient les attributs Envole nécessaires à leur fonctionnement
* L’Active Directory contient le mot de passe et les informations de changement de mot de passe.

Actuellement, eole-SSO et LemonLDAP::NG ne permettent pas une utilisation totalement fonctionnelle des deux sources :

* Soit nous utilisons OpenLDAP et nous n’avons pas les informations d’obligation de changement de mot de passe
* Soit nous utilisons l’Active Directory et nous n’avons pas les attributs Envole

La détection de l’obligation de changement de mot de passe vient du mécanisme des "politiques de mot de passe LDAP":https://ldapwiki.com/wiki/Password%20Policy qui ne peut pas facilement être émulé en synchronisant des attributs de l’active directory vers OpenLDAP (impossible d’ajouter l’attribut *@pwdLastSet@* qui n’est défini par aucun schéma LDAP).

h3. Proposition

Les solutions SSO devraient, dans le cadre d’un fonctionnement mixte *AD* / *OpenLDAP* :

* Tenter d’authentifier l’utilisateur sur l’active directory et détecter le "besoin de changement de mot de passe":https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/blob/master/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/AD.pm#L45
* Procéder au changement de mot de passe sur l’active directory
* aller chercher les informations utilisateur dans l’OpenLDAP

h4. LemoLDAP::NG

Cette solution de SSO permet de "combinier des modules":https://lemonldap-ng.org/documentation/latest/authcombination.html, il est ainsi possible de déclarer :

* le module *@AD@* pour l’"authentification uniquement":https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/blob/master/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/AD.pm
* le module *@LDAP@* pour les "informations utilisateurs":https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/blob/master/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/LDAP.pm
* le module *@AD@* pour la "gestion du changement de mot de passe":https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/blob/master/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Password/AD.pm

L’inconvénient est que le module d’authentification *@AD@* ne fait pas lui même la recherche du *@DN@* de l’utilisateur qui est "délégué à son parent":https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/blob/master/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/LDAP.pm#L42 ce qui ne permet pas "d’avoir le même *@DN@* pour les deux bases":https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2435

Un contournement pourrait être de déclarer un module d’authentification personnalisé, dérivé du module "AD":https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/blob/master/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/AD.pm qui prendrait en charge cette résolution mais il faut vérifier les interactions entre ces modules qui semblent partager la même source de *@DN@*:

* https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/blob/master/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/LDAP.pm#L37
* https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/blob/master/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/LDAP.pm#L79

Il semble donc qu’il faille créer un dérivé du module d’authentification (@Scribe.pm@ ?) de ces deux modules afin de rechercher stocker le *@DN@* de l’AD chacun dans un attribut différent. Peut-être aussi un dérivé du module de changement de mot de passe qui "utilise aussi le *@DN@*":https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/blob/master/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Password/AD.pm#L33.

h4. EOLE SSO

Il semble possible de détecter le changement de mot de passe pour un coût assez faible :

* Jouer l’authentification sur l’active directory et détecter l’exception *@ldap.INVALID_CREDENTIALS@*
** En cas de mauvais mot de passe
*** l’exception contient un attribut chaîne de caractère *@info@* ayant pour valeur *@80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, v1db1@*
** En cas de mot de passe à changer
*** l’exception contient un attribut chaîne de caractère *@info@* ayant pour valeur *@80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 773, v1db1@*
* Le formulaire de changement de mot de passe doit procéder au changement de mot de passe (en utilisant "changepasswrdeole.pl":https://dev-eole.ac-dijon.fr/projects/eole-ad/repository/revisions/master/entry/sbin/changepasswordeole.pl ?)

Pour tester, j’ai utilisé le petit script suivant :

<pre><code class="python">
#!/usr/bin/python3

import ldap
conn = ldap.initialize('ldaps://addc.domscribe.ac-test.fr')
conn.protocol_version = 3

ad_conn = ldap.initialize('ldaps://addc.domscribe.ac-test.fr')
ad_conn.protocol_version = 3

try:
ad_conn.simple_bind_s('CN=admin,CN=Users,DC=domscribe,DC=ac-test,DC=fr', 'MauvaisMot2Passe!')
except Exception as err:
print("AD BAD PASSWORD: {}".format(err))

try:
ad_conn.simple_bind_s('CN=prof.6a,CN=Users,DC=domscribe,DC=ac-test,DC=fr', 'Eole12345!')
except Exception as err:
print("AD MUST CHANGE: {}".format(err))

openldap_conn = ldap.initialize('ldap://127.0.0.1')
openldap_conn.protocol_version = 3

try:
openldap_conn.simple_bind_s('uid=admin,ou=local,ou=personnels,ou=utilisateurs,ou=0000000A,ou=ac-test,ou=education,o=gouv,c=fr', 'MauvaisMot2Passe!')
except Exception as err:
print("OPENLDAP BAD PASSWORD: {}".format(err))

try:
openldap_conn.simple_bind_s('uid=prof.6b,ou=local,ou=personnels,ou=utilisateurs,ou=0000000A,ou=ac-test,ou=education,o=gouv,c=fr', 'Eole12345!')
except Exception as err:
print("OPENLDAP MUST CHANGE: {}".format(err))
</code></pre>

Qui renvoit:

<pre>
AD BAD PASSWORD: {'desc': 'Invalid credentials', 'info': '80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, v1db1'}
AD MUST CHANGE: {'desc': 'Invalid credentials', 'info': '80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 773, v1db1'}
OPENLDAP BAD PASSWORD: {'desc': 'Invalid credentials'}
OPENLDAP MUST CHANGE: {'desc': 'Invalid credentials'}
</pre>

Le module *@LemonLDAP::NG@* fait ce "genre de détection aussi":https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/blob/master/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/AD.pm#L79.

Retour