Je souhaite valider un ensemble d'informations d'identification sur le contrôleur de domaine. par exemple:
Username: STACKOVERFLOW\joel
Password: splotchy
Méthode 1. Interroger Active Directory avec l'emprunt d'identité
Beaucoup de gens suggèrent d'interroger Active Directory pour quelque chose. Si une exception est levée, vous savez que les informations d'identification ne sont pas valides - comme suggéré dans cette question de stackoverflow .
Cette approche présente cependant de sérieux inconvénients :
Vous authentifiez non seulement un compte de domaine, mais vous effectuez également une vérification d'autorisation implicite. Autrement dit, vous lisez les propriétés de l'AD à l'aide d'un jeton d'emprunt d'identité. Que faire si le compte par ailleurs valide n'a aucun droit de lecture à partir de l'AD? Par défaut, tous les utilisateurs ont un accès en lecture, mais les stratégies de domaine peuvent être définies pour désactiver les autorisations d'accès pour les comptes restreints (et / ou les groupes).
La liaison avec l'AD a une surcharge importante, le cache de schéma AD doit être chargé au niveau du client (cache ADSI dans le fournisseur ADSI utilisé par DirectoryServices). C'est à la fois le réseau et le serveur AD, qui consomme des ressources - et est trop cher pour une opération simple comme l'authentification d'un compte utilisateur.
Vous comptez sur un échec d'exception pour un cas non exceptionnel, et supposez que cela signifie un nom d'utilisateur et un mot de passe invalides. D'autres problèmes (par exemple une panne de réseau, une panne de connectivité AD, une erreur d'allocation de mémoire, etc.) sont alors interprétés à tort comme un échec d'authentification.
Méthode 2. API LogonUser Win32
D'autres ont suggéré d'utiliser la LogonUser()
fonction API. Cela semble bien, mais malheureusement, l'utilisateur appelant a parfois besoin d'une autorisation généralement donnée uniquement au système d'exploitation lui-même:
Le processus appelant LogonUser requiert le privilège SE_TCB_NAME. Si le processus appelant ne dispose pas de ce privilège, LogonUser échoue et GetLastError renvoie ERROR_PRIVILEGE_NOT_HELD.
Dans certains cas, le processus qui appelle LogonUser doit également avoir le privilège SE_CHANGE_NOTIFY_NAME activé; sinon, LogonUser échoue et GetLastError renvoie ERROR_ACCESS_DENIED. Ce privilège n'est pas requis pour le compte système local ou les comptes membres du groupe administrateurs. Par défaut, SE_CHANGE_NOTIFY_NAME est activé pour tous les utilisateurs, mais certains administrateurs peuvent le désactiver pour tout le monde.
Attribuer le privilège « Agir en tant que partie du système d'exploitation » n'est pas quelque chose que vous voulez faire bon gré mal gré - comme Microsoft le souligne dans un article de la base de connaissances :
... le processus qui appelle LogonUser doit avoir le privilège SE_TCB_NAME (dans le Gestionnaire des utilisateurs, il s'agit du droit « Agir en tant que partie du système d'exploitation »). Le privilège SE_TCB_NAME est très puissant et ne doit être accordé à aucun utilisateur arbitraire uniquement pour qu'il puisse exécuter une application qui doit valider les informations d'identification.
En outre, un appel à LogonUser()
échouera si un mot de passe vide est spécifié.
Quelle est la bonne façon d'authentifier un ensemble d'informations d'identification de domaine?
Il se trouve que j'appelle à partir de code managé, mais c'est une question Windows générale. On peut supposer que les clients ont installé .NET Framework 2.0.