Así es como funciona ValidateCredentials(string, string)
: Primero, intenta autenticarse con las opciones de contexto Negotiate
, Signing
y Sealing
. Si esto falla, intenta de nuevo con SimpleBind
y SecureSocketLayer
.
El problema es que el formato NT4 (AKA "legacy", AKA "nombre de nivel inferior") (DOMAIN\UserName
, o más correctamente, NetBiosName\SamAccountName
) no funciona con Negotiate. Pero funciona con SimpleBind.
Entonces, ¿qué ocurre cuando se llama al método de 2 parámetros ValidateCredentials()
, es que falla al usar Negotiate porque no le gusta el formato NT4, y luego falla al usar el enlace simple.
Durante mis propias pruebas, he descubierto que la razón por la que falla incluso después de volver a utilizar el enlace simple es que no solo está utilizando SimpleBind. Está usando SimpleBind
plus SecureSocketLayer
. Esto significa que aún fallará si el servidor de Active Directory no está configurado correctamente para usar SSL (un escenario común para entornos de prueba).
Como se mencionó en uno de los comentarios, NUNCA, NUNCA, NUNCA desea utilizar SimpleBind
por sí mismo (sin SecureSocketLayer
), de lo contrario, sus contraseñas se envían a través de la red en texto sin formato.
En la naturaleza, he visto que algunos sistemas de Active Directory no permiten el uso de enlaces simples en absoluto, por lo que debe hacer que funcione con Negociar.
que he encontrado 2 maneras de hacer frente a este problema:
1) Si todo está sucediendo en el mismo dominio, debe ser capaz de llamar ValidateCredentials
sólo con el nombre de usuario (nombre de cuenta SAM), dejando fuera la parte "DOMINIO \". Entonces, funcionará correctamente la primera vez con Negociar.
2) Si la parte de dominio es importante porque puede haber varios dominios implicados (es decir, Domain1\UserA
y Domain2\UserA
son personas diferentes), entonces se vuelve un poco más complicado. En este caso, lo que terminé haciendo fue traducir el nombre NT4 (DOMINIO \ Usuario) al formato "nombre principal del usuario" (por ejemplo, [email protected]
). Hay un par de maneras diferentes de hacer esto.Lo más fácil es, probablemente, utilizar la sobrecarga de 3 parámetros de UserPrincipal.FindByIdentity()
, y luego tomar el valor de la propiedad UserPrincipalName
en el resultado. Otra forma sería usar un DirectorySearcher
y consultar LDAP://domain
para la propiedad userPrincipalName
del usuario con el valor correspondiente sAMAccountName
. Nota: esta solución solo funcionará si todos los dominios involucrados están en el mismo bosque.
Editar la pregunta para incluir todo el método. Intentaremos la sugerencia de ContextOption. Gracias. –
B-Rain, La referencia de ContextOption me indicó la dirección correcta. Terminé usando ContextOptions.Negotiate en mi llamada a AD y ContextOptions.SimpleBind en las credenciales de validación. Simple Bind funcionará para mí ya que el sitio estará protegido por SSL. Gracias por su ayuda. –
Subió tanto la pregunta como la respuesta porque esto también me ayudó en mi situación. En mi caso, mi máquina de desarrollo (donde el inicio de sesión funciona sin contexto especificado) está en la zona segura de la red, pero el servidor web (donde el inicio de sesión no funciona sin el contexto especificado) está en la DMZ. Usé la misma configuración que @Billy Logan: negociar en la llamada a AD y SimpleBind en la llamada de validación. – arootbeer