¿Evento global OnLoggedIn en ASP.net?

¿Hay alguna forma de recibir una notificación cuando un usuario inicia sesión en un sitio web de ASP.net?

Nota:: Un usuario puede iniciar sesión sin visitar una "página de inicio de sesión". Si existe la cookie "recuérdame", pueden acceder a una página arbitraria e iniciar sesión.

Cuando un usuario inicia sesión, quiero obtener información relacionada con la sesión.

Nota:: Ahí está el Login.LoggedIn evento. El problema es que ese control no existe en todas las páginas; y la única página en la que está presente (Login.aspx) no llama OnLoggedIn evento.

De la misma manera que Global.asax tiene un mundial Al inicio de la sesión notificación:

void Session_Start(object sender, EventArgs e) 
{
}

Supongo que en algún lugar hay un En usuario conectado notificación:

void LoggedIn(object sender, EventArgs e)
{
}

Lectura adicional

preguntado el 12 de junio de 12 a las 19:06

Odio cuando busco en Google mi problema (Evento OnLoggedin global de asp.net), y el resultado principal es mi propia pregunta. -

4 Respuestas

Creo que no tienes un lugar único para hacer eso. En mi caso (MVC + log4net) uso esto:

  • In Global.asax Busco usuarios autenticados con cookies preexistentes.

    protected void Session_Start()
    {
        string ip = HttpContext.Current.Request.UserHostAddress;
    
        log.InfoFormat("Starting session: {0} from {1}.",Session.SessionID, ip);
    
        if ((HttpContext.Current != null) &&
            (HttpContext.Current.User != null) &&
            (HttpContext.Current.User.Identity.IsAuthenticated) )
        {
            string user = HttpContext.Current.User.Identity.Name;
            string type = "Cookie";
    
            log.InfoFormat("User {0} logged in with {1}.", user, type);
        }
    
    }
    
  • En mi controlador de cuentas, verifico los inicios de sesión locales (estoy usando la plantilla de aplicación de Internet de MVC4, pero puede hacerlo en su Login.OnLoggedIn si está utilizando formularios web)

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult Login(LoginModel model, string returnUrl)
    {
        if (ModelState.IsValid && WebSecurity.Login(model.EMail, model.Password, persistCookie: model.RememberMe))
        {
            string user = model.EMail;
            string type = "Forms";
    
            log.InfoFormat("User {0} logged in with {1}.", user, type);
    
            return RedirectToLocal(returnUrl);
        }
    
        // If we got this far, something failed, redisplay form
        ModelState.AddModelError("", "The user name or password provided is incorrect.");
        log.ErrorFormat("Bad password or user name. User={0}", model.EMail, model.Password);
        return View(model);
    }
    
  • Pero también necesito verificar los inicios de sesión de OAuth, así:

    [AllowAnonymous]
    public ActionResult ExternalLoginCallback(string returnUrl)
    {
        AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
        if (!result.IsSuccessful)
        {
            log.Debug("External login failure.");
    
            return RedirectToAction("ExternalLoginFailure");
        }
    
        if (OAuthWebSecurity.Login(result.Provider, result.ProviderUserId, createPersistentCookie: false))
        {
            log.InfoFormat("User {0} logged in with External {1} login. External UserID = {2}",
                Membership.GetUser(OAuthWebSecurity.GetUserName(result.Provider, result.ProviderUserId)).UserName,
                result.Provider,
                result.ProviderUserId);
    
            return RedirectToLocal(returnUrl);
        }
    
        ...
    }
    

Respondido 25 Oct 12, 09:10

Puedes hacer el cheque en Application_AuthenticateRequest en global.asax, es el lugar donde puede verificar si la solicitud está iniciada o no junto con los datos de su sesión, y decidir si los datos de la sesión necesitan inicialización como usted dice.

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
    string cookieName = FormsAuthentication.FormsCookieName;
    HttpCookie authCookie = Context.Request.Cookies[cookieName];

    //  check for logged in or not
    if (null != authCookie)
    {
        // is logged in... check if the session needs init

    }   
}

O los mismos resultados con

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
    //  check for logged in or not
    if(HttpContext.Current.User != null && 
        HttpContext.Current.User.Identity != null 
            && HttpContext.Current.User.Identity.IsAuthenticated)
    {
        // is logged in... check if the session needs init

    }   
}    

Respondido el 13 de junio de 12 a las 14:06

Realmente no puedo estar atado a Forms autenticación, o al uso de una cookie de Formularios. Si no uso la autenticación de formularios, o no hay una cookie, aún pueden iniciar sesión. - Ian Boyd

@IanBoyd Si ves que tengo y la otra forma de verificar ... con el HttpContext.Current.User.Identity.IsAuthenticated, solo el primero es más rápido. - Aristóteles

estoy haciendo algo mal con el Application_AuthenticateRequest, se llama 7 veces con el usuario. - Ian Boyd

Se llama a @IanBoyd en cada solicitud de cualquier recurso de asp.net para verificar si necesita o no autenticación, puede hacer una verificación más de qué archivo es, y si es aspx, o el controlador deja que haga el resto. Utilizar el HttpContext.Current.Request.Path y System.IO.Path.GetExtension(cTheFile) para comprobar la extensión - lo siento debe dejar la computadora, volveré en unas horas. Espero que esto ayude - Aristóteles

Puede llamar a su código en esos dos lugares: OnLoggedIn evento del Login control y también cuando se inicia la sesión (usando el Session_Start evento en su Global.asax), ya que esta será la primera solicitud con los datos del usuario. Allí puede verificar si el usuario está logueado y, de ser así, hacer lo que necesita.

Respondido el 12 de junio de 12 a las 19:06

OnLoggedIn El evento no se llama cuando el usuario navega por el sitio web. - Ian Boyd

Exactamente, es por eso que sugiero llamar al mismo método que necesita en su Session_Start - Ivo

Eso parece implicar que no hay un evento global "OnLoggedIn". - Ian Boyd

No hay. Si coloca el código en una clase, podrá llamarlo desde ambos lugares y resolver su problema. - Ivo

¿Alguna otra situación atrapada? Sé que los usuarios pueden permanecer conectados, incluso si finaliza una sesión (es decir, se recicla el grupo de aplicaciones). - Ian Boyd

Aunque técnicamente estar conectado es lo mismo que estar autenticado, tengo un modelo mental diferente de esto.

En mi opinión, las tres cosas siguientes son cuestiones separadas:

  • El usuario tiene/obtiene una sesión
  • El usuario está autenticado
  • El usuario ha iniciado sesión

Para mí el último de estos significa: "Se ha creado una sesión para el usuario, el usuario está autenticado y la sesión se ha inicializado para el usuario autenticado".

Con este modelo, un usuario puede iniciar sesión cuando:

  • El usuario inicia sesión en la página de inicio de sesión y la sesión preexistente se inicializa con los datos de usuario necesarios
  • Un usuario previamente autenticado llega al sitio y se crea e inicializa una nueva sesión para él/ella

De manera similar, el usuario se desconecta cuando se destruye su sesión inicializada.

Usar este modelo significará:

  • Puede identificar cuando un usuario "inicie sesión" ya sea en el Login.OnLoggedIn evento el o el Session_Start evento en Global.asax. Por supuesto, el evento de inicio de sesión también se activa para usuarios no autenticados, por lo que debe verificar que el usuario esté autenticado cuando se activa el evento.
  • Puede decir de manera confiable cuándo un usuario "cierra sesión", ya sea cerrando sesión explícitamente o cuando una sesión inicializada correctamente se destruye en el Session_End evento en Global.asax. Digo algo confiable, porque creo que los eventos Session_End no necesariamente se activarán cuando el grupo de aplicaciones se recicle o muera en un bloqueo. Aunque no he probado esto, así que podría estar equivocado.
  • Un usuario puede "iniciar sesión" simultáneamente varias veces. Al menos en IE puede iniciar una "Nueva sesión" desde el menú Archivo. Esto inicia un nuevo IE que no comparte las cookies de sesión con ninguna ventana de IE preexistente. Esto significa que el servidor creará una nueva sesión cuando el usuario ingrese al sitio y, según el mecanismo de autenticación utilizado, podría significar que también tendrá que autenticarse nuevamente.

no te deja"enumerar todos los usuarios conectados actualmente" fuera de la caja. Necesitará crear alguna forma de realizar un seguimiento de eso usted mismo, creo. Esto puede ser más o menos difícil de hacer. Especialmente en el caso de que su aplicación se ejecute en algún tipo de entorno de carga equilibrada, obteniendo una lista de todos los usuarios actuales puede ser complicada.

Respondido el 14 de junio de 12 a las 11:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.