Suplantar usando Autenticación de formularios

Tengo un sitio ASP.NET que debe usar la Autenticación de formularios y no la Autenticación de Windows para acceder a ActiveDirectoryMembershipProvider . El sitio debe usar formularios porque necesitan un formulario de entrada diseñado en lugar de la ventana emergente de autenticación del navegador que usa la autenticación de Windows.

El sitio debe suplantar al usuario que inició sesión a través de Active Directory para acceder a los archivos específicos del usuario.

Sin embargo, WindowsIdentity.GetCurrent() no es lo mismo que HttpContext.Current.User.Identity aunque mi web.config contiene:

     

No puedo usar LoginUser() y WindowsIdentity.Impersonate() porque necesito suplantarme como usuario de AD para obtener sus permisos específicos, y no sé la contraseña del usuario porque Formularios se encarga de iniciar sesión.

¿Es posible que desde el login.aspx.cs, tome el System.Web.UI.WebControls.Login.Password , luego guarde el LoginUser() en una variable de sesión para WindowsIdentity.Impersonate() más tarde? ¿O tal vez un método mucho más seguro de suplantar el camino correcto?

Estoy confundido por qué la autenticación de formularios no puede automáticamente

Leí este http://msdn.microsoft.com/en-us/library/ms998351.aspx pero usa la Autenticación de Windows.

Hacerse pasar por un usuario utilizando la Autenticación de formularios se puede hacer. El siguiente código funciona .

El artículo de Visual Studio Magazine al que se refiere Robert es un excelente recurso. Hay algunos problemas con el código de ejemplo en el artículo, por lo que he incluido algunos códigos de trabajo a continuación.

Nota: Si está utilizando Visual Studio, asegúrese de ejecutarloEjecutar como administrador ” para evitar problemas con la suplantación de locking de UAC.

 // in your login page (hook up to OnAuthenticate event) protected void LoginControl_Authenticate(object sender, AuthenticateEventArgs e) { int token; // replace "YOURDOMAIN" with your actual domain name e.Authenticated = LogonUser(LoginUser.UserName,"YOURDOMAIN",LoginUser.Password,8,0,out token); if (e.Authenticated) { Session.Add("principal", new WindowsPrincipal(new WindowsIdentity(new IntPtr(token)))); } } [DllImport("advapi32.dll", SetLastError = true)] public static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out int TokenHandle); // in global.asax.cs void Application_PreRequestHandlerExecute(object send, EventArgs e) { if (Thread.CurrentPrincipal.Identity.IsAuthenticated == true && HttpContext.Current.Session != null) { WindowsPrincipal windowsPrincipal = (WindowsPrincipal)Session["principal"]; Session["principal"] = (GenericPrincipal)Thread.CurrentPrincipal; Thread.CurrentPrincipal = windowsPrincipal; HttpContext.Current.User = windowsPrincipal; HttpContext.Current.Items["identity"] = ((WindowsIdentity)windowsPrincipal.Identity).Impersonate(); } } // in global.asax.cs void Application_PostRequestHandlerExecute(object send, EventArgs e) { if (HttpContext.Current.Session != null && Session["principal"] as GenericPrincipal != null) { GenericPrincipal genericPrincipal = (GenericPrincipal)Session["principal"]; Session["principal"] = (WindowsPrincipal)Thread.CurrentPrincipal; Thread.CurrentPrincipal = genericPrincipal; HttpContext.Current.User = genericPrincipal; ((WindowsImpersonationContext)HttpContext.Current.Items["identity"]).Undo(); } } // test that impersonation is working (add this and an Asp:Label to a test page) protected void Page_Load(object sender, EventArgs e) { try { // replace YOURSERVER and YOURDB with your actual server and database names string connstring = "data source=YOURSERVER;initial catalog=YOURDB;integrated security=True"; using (SqlConnection conn = new SqlConnection(connstring)) { conn.Open(); SqlCommand cmd = new SqlCommand("SELECT SUSER_NAME()", conn); using (SqlDataReader rdr = cmd.ExecuteReader()) { rdr.Read(); Label1.Text = "SUSER_NAME() = " + rdr.GetString(0); } } } catch { } } 

Actualizar:

También debe manejar Application_EndRequest , porque las llamadas como Response.End() omitirán Application_PostRequestHandlerExecute .

Otro problema es que WindowsIdentity puede obtener basura recolectada, por lo que debe crear una nueva WindowsIdentity y WindowsPrincipal desde el token de inicio de sesión en cada solicitud.

Actualización2:

No estoy seguro de por qué esto se está volviendo downvoted, porque funciona. He agregado la firma de Pinvoke y algunos códigos de prueba. Nuevamente, inicie Visual Studio usando ” Ejecutar como administrador “. Busca cómo hacerlo si no sabes cómo.

Si sus usuarios utilizan IE, puede activar la seguridad integrada para el sitio web y sus usuarios serán autenticados de forma silenciosa (sin diálogo de inicio de sesión ni página de inicio de sesión). Tu suplantación funcionará. Si necesita orientar otros navegadores, es posible que esto no funcione (probablemente se le presentará al usuario un cuadro de diálogo de inicio de sesión).

Su suplantación actual nunca funcionará porque sus usuarios inician sesión usando una cuenta que no sea su cuenta de dominio. No puede esperar que el sitio suplante a un usuario que no haya proporcionado sus credenciales. Eso iría en contra de los principios básicos de seguridad.

Puede encontrar esto útil:

  • cómo crear una pantalla de inicio de sesión que permita a los usuarios Admin iniciar sesión como otro usuario en la base de datos de usuarios

EDITAR

Al leer su pregunta más de cerca, no estoy seguro si ese enfoque funcionaría con su escenario; cuando inicia sesión utilizando la Autenticación de formularios y Personifica al usuario de Active Directory

Recientemente, tuvimos el mismo problema, el cliente quería que sus usuarios puedan iniciar sesión por cuenta de AD y, a continuación, esta credencial debe utilizarse para acceder al servicio de análisis, así como a todas las demás bases de datos. Lo querían de esa manera porque implementaron un sistema de auditoría y todos los accesos se deben hacer con la cuenta iniciada actual.

Probamos la autenticación Forms y la API Win32 LogonUser () para suplantar a la parte, funcionó pero también nos pide la contraseña del usuario como texto sin formato. Más tarde, decidimos utilizar la autenticación de Windows, nos ahorra mucho tiempo (no más autenticación AD, suplantación manual). Por supuesto, tampoco había una página de inicio de sesión elegante.

Por si acaso, y un poco tarde, encontré algo que funciona para mí y es muy simple, pero por supuesto es solo para fines de prueba …

Simplemente configure una cookie con su nombre de usuario.

 //Login button. You can give whatever input to the form protected void Login_Click(object sender, EventArgs e) { FormsAuthentication.SetAuthCookie("your_username", createPersistentCookie: true); Response.Redirect("~/"); } 

Cualquier comentario aceptado …

En Visual Studio instala NuGet Abre tu solución

Luego, en la consola del paquete, ejecute Install-Package 51Degrees.mobi

Luego agregará 51Degrees a su sitio web. A continuación, puede editar 51Degrees.mobi.config en los datos de su aplicación para eliminar la sección de redirección.

Ahora tendrá capacidades de navegador actualizadas