tag route net mvc form for asp c# asp.net-mvc authentication ntlm
descarga del código fuente.

c# - route - ¿Cómo admitir la autenticación NTLM con el repliegue de forma en ASP.NET MVC?



form net core (3)

¿Cómo puedo implementar lo siguiente en la aplicación MVC de ASP.NET?

  1. El usuario abre el sitio web de la intranet.
  2. el usuario se autentica silenciosamente si es posible
  3. Si la autenticación NTLM no funcionó, muestre el formulario de inicio de sesión al usuario
  4. el usuario indica la contraseña de inicio de sesión y selecciona el dominio de la lista de dominios predefinidos
  5. El usuario está autenticado en código usando AD

Sé cómo implementar 4 y 5, pero no puedo encontrar información sobre cómo combinar NTLM y formularios. De modo que nunca se muestra el diálogo de inicio de sesión / contraseña nativo de NTLM: autenticación transparente o página de inicio de sesión atractiva.

¿Cómo debería funcionar? ¿Se debe pedir al usuario que inicie sesión y contraseña? ¿Se pueden usar sus credenciales actuales (nombre de usuario del dominio) sin solicitar ingresar el nombre de usuario y la contraseña?

ACTUALIZACIÓN para estos, investigando el mismo problema:

Cuando pregunté esto, no entendía completamente cómo funciona la autenticación NTLM internamente. Lo importante aquí para comprender es que si el navegador del usuario no admite NTLM correctamente o si el usuario deshabilita la compatibilidad con NTLM, el servidor nunca tendrá la oportunidad de solucionar este problema.

Cómo funciona la autenticación de Windows:

  1. Cliente envía una solicitud HTTP regular al servidor
  2. El servidor responde con el estado HTTP 401 e indica que se debe utilizar la autenticación NTLM para acceder a los recursos
  3. Cliente envía mensaje NTLM tipo 1
  4. El servidor responde con un mensaje tipo 2 de NTLM con desafío
  5. Cliente envía mensaje Type3 con respuesta a desafío
  6. El servidor responde con el contenido real solicitado

Como puede ver, el navegador que no admite NTLM no irá al paso (3), en su lugar se mostrará al usuario la página de Error 401 generada por IIS.

Si el usuario no tiene credenciales, después de cancelar la ventana de diálogo emergente de autenticación NTLM, el navegador no continuará (3) también.

Por lo tanto, no tenemos la oportunidad de redirigir automáticamente a los usuarios a la página de inicio de sesión personalizada.

La única opción aquí es tener una página de "pasarela" en la que decidimos si el usuario debe admitir NTLM y, de ser así, redirigir a la página de inicio protegida de NTLM.

Y si no, muestre el formulario de inicio de sesión y permita la autenticación ingresando manualmente el inicio de sesión y la contraseña.

La decisión generalmente se toma en función de la dirección IP de los usuarios y / o el nombre del host, ya sea haciendo coincidir los rangos de IP o verificando la tabla de IP predefinidas.


Este artículo podría apuntarle en la dirección correcta. Básicamente, tiene dos aplicaciones en dos directorios virtuales con el mismo nombre de host. Una aplicación usa la autenticación de formularios, una usa Windows. El que utiliza la autenticación de Windows crea una cookie de autenticación de formulario válida y la redirige al segundo directorio virtual.

Autenticación en modo mixto de ASP.NET


No puede tener NTLM y FormsAuthentication en la misma aplicación ASP.NET. Necesitará dos aplicaciones diferentes en directorios virtuales separados.


Tengo esta configuración exacta en producción, configuré mi portal para usar FormsAuth y escribí una función que toma la IP de los visitantes para buscar la cuenta de usuario que ha iniciado sesión en esa IP / PC. Al usar el nombre que encuentro (por ejemplo, DOMAIN/user ), verifico que el dominio coincide con mi dominio y que el nombre de usuario / cuenta es válido en mi proveedor de FormsAth usando Membership.GetUser(<user>) . Si esta llamada devuelve una coincidencia y el usuario está IsApproved creo un FormsAuthenticationTicket y cookie de FormsAuthenticationTicket para el usuario. Tengo más de 400 personas en la red y esto funciona perfectamente, las únicas computadoras que todavía inician sesión son (1. Usuarios sin cuentas en mi portal, 2. Algunos usuarios de MAC / Linux, 3. Usuarios móviles que no iniciaron en la red y tenía Política de grupo habilitar su Firewall a Alto).

El problema con esta solución es que requiere la suplantación de una cuenta de administrador de dominio para consultar a la PC de los usuarios y que usa el código no administrado netapi32.dll .

Aquí está el código que uso (no se proporcionan llamadas a funciones externas, por brevedad). He intentado simplificar esto un poco, ya que tengo MUCHAS llamadas externas.

string account = String.Empty; string domain = String.Empty; string user = String.Empty; ImpersonateUser iu = new ImpersonateUser(); //Helper that Enabled Impersonation if (iu.impersonateValidUser(StringHelper.GetAppSetting("DomainAccount"), StringHelper.GetAppSetting("DomainName"), StringHelper.GetEncryptedAppSetting("DomainAccountPassword"))) { NetWorkstationUserEnum nws = new NetWorkstationUserEnum(); //Wrapper for netapi32.dll (Tested on Vista, XP, Win2K, Win2K3, Win2K8) string host = nws.DNSLookup(Request.UserHostAddress); // netapi32.dll requires a host name, not an IP address string[] users = nws.ScanHost(host); // Gets the users/accounts logged in if (nws.ScanHost(host).Length > 0) { string workstationaccount = string.Empty; if (host.IndexOf(''.'') == -1) // Pick which account to use, I have 99.9% success with this logic (only time doesn''t work is when you run a interactive process as a admin e.g. Run As <process>). { workstationaccount = String.Format("{0}//{1}$",StringHelper.GetAppSetting("DomainName"), host).ToUpper(); } else { workstationaccount = String.Format("{0}//{1}$", StringHelper.GetAppSetting("DomainName"), host.Substring(0, host.IndexOf(''.''))).ToUpperInvariant(); } account = users[users.Length - 1].Equals(workstationaccount) ? users[0] : users[users.Length - 1]; domain = account.Substring(0, account.IndexOf("//")); user = account.Substring(account.IndexOf("//") + 1, account.Length - account.IndexOf("//") - 1); } iu.undoImpersonation(); // Disable Impersonation }

Ahora, utilizando la cuenta que tomamos en la primera función / proceso, ahora intentamos verificar y decidir si debemos mostrar un inicio de sesión o un inicio de sesión automático para el usuario.

MembershipUser membershipUser = Membership.GetUser(user); if (membershipUser != null && membershipUser.IsApproved) { string userRoles = string.Empty; // Get all their roles FormsAuthenticationUtil.RedirectFromLoginPage(user, userRoles, true); // Create FormsAuthTicket + Cookie + }

Escribí una publicación de blog sobre esto hace mucho tiempo, aquí hay un enlace al envoltorio para netapi32.dll y a mi ayudante de personificación que proporcioné en la descarga del código fuente.