Quiero validar un conjunto de credenciales con el controlador de dominio. p.ej:
Username: STACKOVERFLOW\joel
Password: splotchy
Método 1. Consultar Active Directory con suplantación
Mucha gente sugiere consultar Active Directory por algo. Si se lanza una excepción, entonces sabrá que las credenciales no son válidas, como se sugiere en esta pregunta de stackoverflow .
Sin embargo, existen serios inconvenientes en este enfoque :
No solo está autenticando una cuenta de dominio, sino que también está realizando una verificación de autorización implícita. Es decir, está leyendo propiedades del AD utilizando un token de suplantación. ¿Qué sucede si la cuenta que de otro modo es válida no tiene derechos de lectura del AD? De forma predeterminada, todos los usuarios tienen acceso de lectura, pero las políticas de dominio se pueden configurar para deshabilitar los permisos de acceso para cuentas (o grupos) restringidos.
La vinculación contra AD tiene una sobrecarga importante, la caché del esquema de AD debe cargarse en el cliente (caché ADSI en el proveedor ADSI utilizado por DirectoryServices). Esto consume recursos tanto de la red como del servidor AD, y es demasiado caro para una operación simple como autenticar una cuenta de usuario.
Está confiando en una falla de excepción para un caso no excepcional, y asumiendo que eso significa un nombre de usuario y contraseña no válidos. Otros problemas (por ejemplo, falla de red, falla de conectividad de AD, error de asignación de memoria, etc.) se interpretan erróneamente como falla de autenticación.
Método 2. API LogonUser Win32
Otros han sugerido usar la LogonUser()
función API. Esto suena bien, pero desafortunadamente, el usuario que llama a veces necesita un permiso que generalmente solo se otorga al sistema operativo:
El proceso que llama a LogonUser requiere el privilegio SE_TCB_NAME. Si el proceso de llamada no tiene este privilegio, LogonUser falla y GetLastError devuelve ERROR_PRIVILEGE_NOT_HELD.
En algunos casos, el proceso que llama a LogonUser también debe tener habilitado el privilegio SE_CHANGE_NOTIFY_NAME; de lo contrario, LogonUser falla y GetLastError devuelve ERROR_ACCESS_DENIED. Este privilegio no es necesario para la cuenta del sistema local o las cuentas que son miembros del grupo de administradores. De forma predeterminada, SE_CHANGE_NOTIFY_NAME está habilitado para todos los usuarios, pero algunos administradores pueden deshabilitarlo para todos.
Distribuir el privilegio " Actuar como parte del sistema operativo " no es algo que quiera hacer, como lo señala Microsoft en un artículo de la base de conocimientos :
... el proceso que llama a LogonUser debe tener el privilegio SE_TCB_NAME (en el Administrador de usuarios, este es el derecho " Actuar como parte del sistema operativo "). El privilegio SE_TCB_NAME es muy poderoso y no debe otorgarse a ningún usuario arbitrario solo para que pueda ejecutar una aplicación que necesita validar las credenciales.
Además, una llamada a LogonUser()
fallará si se especifica una contraseña en blanco.
¿Cuál es la forma correcta de autenticar un conjunto de credenciales de dominio?
Resulta que estoy llamando desde un código administrado, pero esta es una pregunta general de Windows. Se puede suponer que los clientes tienen instalado .NET Framework 2.0.