asp.net - net - Hacerse pasar por la autenticación de formularios
autenticacion windows asp net (6)
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:
<authentication mode="Forms">
<forms loginUrl="login.aspx" timeout="480"/>
</authentication>
<identity impersonate="true" />
No puedo usar LoginUser()
y WindowsIdentity.Impersonate()
porque necesito hacerme pasar por el usuario AD para obtener sus permisos específicos, y no conozco la contraseña del usuario porque Forms se encarga de iniciar sesión.
¿Es posible tal vez desde login.aspx.cs, tomar el System.Web.UI.WebControls.Login.Password
, luego guardar 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 hacerse pasar por la manera correcta?
Estoy confundido por qué la autenticación de formularios no puede automáticamente <identity impersonate="true" />
He leído este http://msdn.microsoft.com/en-us/library/ms998351.aspx pero utiliza la autenticación de Windows.
En Visual Studio instala NuGet. Abre tu solución.
Luego en la consola de paquetes ejecute Install-Package 51Degrees.mobi
Luego agregará 51 grados a su sitio web. Luego puede editar el 51Degrees.mobi.config en los Datos de su aplicación para eliminar la sección de redireccionamiento.
Ahora tendrá capacidades de navegador actualizadas
Hace poco tuvimos el mismo problema, el cliente quería que sus usuarios pudieran iniciar sesión con una cuenta de AD y luego esta credencial debe usarse 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 deben ser realizados por la cuenta actual iniciada.
Probamos la autenticación de formularios y la API Win32 LogonUser () para suplantar 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 de AD, suplantar manualmente). Por supuesto, tampoco había una página de inicio de sesión elegante.
Por si acaso, y un poco tarde, encontré algo que me funciona y es muy simple pero, por supuesto, solo para pruebas ...
Solo configura una cookie con tu 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 ...
Puede encontrar esto útil:
EDITAR
Sin embargo, al leer su pregunta más detenidamente, no estoy seguro de si ese enfoque funcionaría con su escenario; cuando inicia sesión con Autenticación de formularios y Suplantación de usuario de Active Directory
Se puede suplantar a un usuario mediante la autenticación de formularios. El siguiente código funciona .
El artículo de la revista Visual Studio mencionado por 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 ejecutarlo " Ejecutar como administrador " para evitar problemas con el bloqueo de la suplantación 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 un nuevo WindowsIdentity y WindowsPrincipal desde el token de inicio de sesión en cada solicitud.
Actualización2:
No estoy seguro de por qué esto está siendo abatido, porque funciona. He añadido la firma pinvoke y un código de prueba. Nuevamente, inicie Visual Studio usando " Ejecutar como administrador ". Google 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 se autenticarán de forma silenciosa (sin diálogo de inicio de sesión, sin página de inicio de sesión). Tu suplantación funcionará. Si necesita apuntar a otros navegadores, es posible que esto no funcione (el usuario probablemente tendrá un cuadro de diálogo de inicio de sesión).
Su suplantación actual nunca funcionará porque sus usuarios inician sesión con una cuenta que no sea su cuenta de dominio. No puede esperar que el sitio se haga pasar por un usuario que no haya proporcionado sus credenciales. Eso iría en contra de los principios básicos de seguridad.