Authentification en PHP à l'aide de LDAP via Active Directory

104

Je cherche un moyen d'authentifier les utilisateurs via LDAP avec PHP (avec Active Directory en tant que fournisseur). Idéalement, il devrait pouvoir fonctionner sur IIS 7 ( adLDAP le fait sur Apache). Quelqu'un avait-il fait quelque chose de similaire, avec succès?

  • Edit: Je préfère une bibliothèque / classe avec du code prêt à l'emploi ... Ce serait idiot d'inventer la roue quand quelqu'un l'a déjà fait.
DV.
la source
Je pense que drupal a un module pour thatr
redben

Réponses:

167

Importer une bibliothèque entière semble inefficace lorsque tout ce dont vous avez besoin est essentiellement de deux lignes de code ...

$ldap = ldap_connect("ldap.example.com");
if ($bind = ldap_bind($ldap, $_POST['username'], $_POST['password'])) {
  // log them in!
} else {
  // error message
}
ceejayoz
la source
43
Certaines installations d'AD se lieront avec succès si le mot de passe fourni est vide. Attention à ça! Vous devrez peut-être vous assurer d'un mot de passe non vide avant d'essayer de vous authentifier.
diolemo
@diolemo Existe-t-il un moyen d'éviter cela sans vérifier si le mot de passe est vide?
Naftali aka Neal
@Neal Vous pourrez peut-être l'utiliser ldap_set_optionpour le faire se comporter d'une manière différente. Peut-être définir la version du protocole? Vous devrez expérimenter. Je vous suggère personnellement de vérifier quand même si un mot de passe est vide, juste pour être sûr.
diolemo
À l'éditeur anonyme: non, à ma connaissance, le nettoyage des entrées n'est pas nécessaire ici, comme le ldap_bindserait le traitement et les caractères spéciaux ne sont pas un problème.
ceejayoz
14

On pourrait penser que simplement authentifier un utilisateur dans Active Directory serait un processus assez simple utilisant LDAP en PHP sans avoir besoin d'une bibliothèque. Mais il y a beaucoup de choses qui peuvent le compliquer assez rapidement:

  • Vous devez valider l'entrée. Un nom d'utilisateur / mot de passe vide passerait autrement.
  • Vous devez vous assurer que le nom d'utilisateur / mot de passe est correctement codé lors de la liaison.
  • Vous devriez crypter la connexion à l'aide de TLS.
  • Utilisation de serveurs LDAP séparés pour la redondance en cas de panne.
  • Obtention d'un message d'erreur informatif si l'authentification échoue.

Il est en fait plus facile dans la plupart des cas d'utiliser une bibliothèque LDAP prenant en charge ce qui précède. J'ai finalement roulé ma propre bibliothèque qui gère tous les points ci-dessus: LdapTools (Eh bien, pas seulement pour l'authentification, il peut faire beaucoup plus). Il peut être utilisé comme suit:

use LdapTools\Configuration;
use LdapTools\DomainConfiguration;
use LdapTools\LdapManager;

$domain = (new DomainConfiguration('example.com'))
    ->setUsername('username') # A separate AD service account used by your app
    ->setPassword('password')
    ->setServers(['dc1', 'dc2', 'dc3'])
    ->setUseTls(true);
$config = new Configuration($domain);
$ldap = new LdapManager($config);

if (!$ldap->authenticate($username, $password, $message)) {
    echo "Error: $message";
} else {
    // Do something...
}

L'appel d'authentification ci-dessus:

  • Vérifiez que ni le nom d'utilisateur ni le mot de passe ne sont vides.
  • Assurez-vous que le nom d'utilisateur / mot de passe est correctement codé (UTF-8 par défaut)
  • Essayez un autre serveur LDAP au cas où l'un serait en panne.
  • Cryptez la demande d'authentification à l'aide de TLS.
  • Fournissez des informations supplémentaires en cas d'échec (par exemple, compte verrouillé / désactivé, etc.)

Il existe également d'autres bibliothèques pour le faire (comme Adldap2). Cependant, je me suis senti suffisamment obligé de fournir des informations supplémentaires car la réponse la plus votée est en fait un risque de sécurité sur lequel s'appuyer sans aucune validation d'entrée effectuée et sans utiliser TLS.

TchadSikorra
la source
1
Pour les connexions LDAP, TLS a été abandonné au profit de StartTLS: openldap.org/faq/data/cache/605.html .
zenlord
2
@zenlord L'utilisation du ldaps://format pour la connexion est obsolète. Dans mon exemple, lorsque vous spécifiez, setUseTls(true)il utilise le ldap://format, puis émet un StartTLS en utilisant ldap_start_tls($connection). Donc TLS lui-même n'est pas obsolète, il suffit de se connecter en utilisant ldaps://(qui se connecte en fait à LDAP via un port complètement différent).
ChadSikorra
12

Je fais cela simplement en passant les informations d'identification de l'utilisateur à ldap_bind ().

http://php.net/manual/en/function.ldap-bind.php

Si le compte peut se lier à LDAP, il est valide; s'il ne peut pas, ce n'est pas le cas. Si tout ce que vous faites est l'authentification (pas la gestion de compte), je ne vois pas la nécessité d'une bibliothèque.

Scott Reynen
la source
9

J'aime la classe Zend_Ldap , vous ne pouvez utiliser que cette classe dans votre projet, sans Zend Framework.

CMS
la source
1
Je me suis donné la peine de mettre en œuvre ce qui précède pour trouver que c'était pour gérer la non authentification. J'ai l'intention de passer à zend.auth.adapter.ldap
vdidxho