2010-01-20 35 views
25

Estoy usando Form Authentication y enviando una solicitud Aajx al servidor para la autenticación. Basado en el resultado json, el cliente decide dónde ir y qué hacer. Esa es la razón por la que no estoy usando FormsAuthentication.RedirectFromLoginPage para no interferir con la respuesta ajax/json.Cómo establecer Request.IsAuthenticated en true cuando no se usa FormsAuthentication.RedirectFromLoginPage?

En este caso Request.IsAuthenticated devuelve false, incluso después de validar al usuario con Membership.ValidateUser. Entonces me puse la cookie utilizando

FormsAuthentication.SetAuthCookie(username, false); 

Aunque el segundo parámetro, cookie persistente, es falsa, la cookie sigue siendo válido en todas las sesiones del navegador.

¿Alguna idea de cómo realizar el trabajo Request.IsAuthenticated sin utilizar FormsAuthentication.RedirectFromLoginPage?

+0

Es posible que usted no está configurando la cookie correctamente utilizando una petición AJAX ... – Jason

+0

Ha intentado seguir las instrucciones de MSDN en http: //msdn.microsoft.com/en-us/library/bb398896.aspx? –

+0

Esto es particularmente problemático si está intentando generar y devolver un token anti falsificación en su solicitud de autenticación ajax (es decir, un SPA). Asp.Net generará el token para un "usuario", ya que supone que nadie está autenticado actualmente. – SeeNoWeevil

Respuesta

22

Debe actualizar el principal de seguridad actual para la solicitud. Cuando llama al Response. Redirect(...), se realiza una nueva solicitud y se reinicializa el principal de seguridad y se devuelve el valor verdadero de Request.IsAuthenticated en su caso. FormsAuthentication.RedirectFromLoginPage llamadas internas Response. Redirect(...). Puede renovar manualmente la entidad de seguridad de la solicitud actual así:

public void RenewCurrentUser() 
{ 
    System.Web.HttpCookie authCookie = 
     System.Web.HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName]; 
    if (authCookie != null) 
    { 
     FormsAuthenticationTicket authTicket = null; 
     authTicket = FormsAuthentication.Decrypt(authCookie.Value); 

     if (authTicket != null && !authTicket.Expired) 
     { 
      FormsAuthenticationTicket newAuthTicket = authTicket; 

      if (FormsAuthentication.SlidingExpiration) 
      { 
       newAuthTicket = FormsAuthentication.RenewTicketIfOld(authTicket); 
      } 
      string userData = newAuthTicket.UserData; 
      string[] roles = userData.Split(','); 

      System.Web.HttpContext.Current.User = 
       new System.Security.Principal.GenericPrincipal(new FormsIdentity(newAuthTicket), roles); 
     } 
    } 
} 
+0

La renovación manual no es necesaria (especialmente para GenericPrincipal y FormsIdentity), y las credenciales no deben cambiar parcialmente a través de una solicitud, por lo que la cookie se agrega a la respuesta y luego se realiza un ciclo de vida de respuesta/solicitud completamente nuevo. En la siguiente solicitud, se seleccionará la cookie creada por FormsAuthentication.SetAuthCookie(). –

+4

Por supuesto, este método puede considerarse un hack porque no sigue el flujo de autenticación de formularios normales. Pero puede ser útil si desea verificar si el usuario está autenticado en la misma solicitud en la que se realiza la autenticación. –

+1

A veces, aunque lo que necesita es un truco: estaba tratando de hacer las cosas "correctamente" y forzar una redirección, y ponerme en un estado correcto con otros sistemas redirigidos :( –

20

FormsAuthentication.SetAuthCookie

método crea un vale de autenticación para el nombre de usuario suministrado y añade a la colección de las galletas la respuesta, o a la URL si usted es usando autenticación sin cookies.

Ref: msdn

Tener un vistazo a la Forms Authentication Control Flow. La cookie de autenticación se establece en la colección de cookies de respuesta, y debe ser observable en el nivel de protocolo http (por ejemplo, use FireCookie o Fiddler2 para verificar esto).

La membresía solo verifica un nombre de usuario/contraseña. Ni Membership ni SetAuthCookie() modificarán la solicitud actual. Esperan enviar de nuevo la cookie a la persona que llama, y ​​la siguiente solicitud es cuando las propiedades como IsAuthenticated devolverán verdadero.

Tenga en cuenta que se puede reemplazar y ampliar estos procesos automáticos usando encargo IIdentity y IPrincipal y enganchar en los eventos de autenticación si es necesario.

también echar un vistazo a Using Forms Authentication with ASP.NET AJAX

+0

Esta es una gran respuesta. – Greg

+1

+1 para la referencia de Forms Authentication Control Flow. – CGK

+0

He usado Fiddler para ver las cookies en solicitud y respuesta –

2

Redirección después de un POST es la mejor práctica, y se debe considerar la solución correcta.

En algunos casos, es posible que desee averiguar si un usuario está autenticado dentro del alcance de la solicitud de autenticación (por ejemplo, si está ejecutando lógica adicional después de que se realizó la autenticación compartida con otras solicitudes).

En este caso, puede restablecer el valor de Solicitud.IsAuthenticated con el siguiente código:

// set the forms auth cookie 
FormsAuthentication.SetAuthCookie(username, createPersistentCookie); 

// reset request.isauthenticated 
var authCookie = System.Web.HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName]; 
if (authCookie != null) 
{ 
    FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value); 
    if (authTicket != null && !authTicket.Expired) 
    { 
     var roles = authTicket.UserData.Split(','); 
     System.Web.HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(new FormsIdentity(authTicket), roles); 
    } 
} 

ver post aquí: http://abadjimarinov.net/blog/2010/01/24/RenewUserInTheSameRequestInAspdotNET.xhtml

Cuestiones relacionadas