ASP.net中的Global OnLoggedIn事件?

时间:2012-06-12 18:03:27

标签: asp.net forms-authentication stay-logged-in

当用户使用ASP.net网站登录时,是否有通知的方法?

  

注意:用户无需访问“登录页面”即可登录。如果存在“记住我”cookie,他们可以点击任意页面并登录。

当用户登录时,我想获取一些与会话相关的信息。

  

注意:有Login.LoggedIn个事件。问题是每个页面上都不存在该控件;它所在的一个页面(Login.aspx)不会调用OnLoggedIn事件。

Global.asax具有全局会话开始通知的方式相同:

void Session_Start(object sender, EventArgs e) 
{
}

我假设有一个 On User Logged In 通知:

void LoggedIn(object sender, EventArgs e)
{
}

奖金阅读

4 个答案:

答案 0 :(得分:7)

我认为你没有一个独特的地方可以做到这一点。在我的情况下(MVC + log4net)我用这个:

  • Global.asax中,我使用预先存在的Cookie检查经过身份验证的用户。

    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);
        }
    
    }
    
  • 在我的帐户控制器中,我检查本地登录(我正在使用MVC4中的Internet应用程序模板,但如果您使用的是Web表单,则可以在Login.OnLoggedIn中执行此操作)

    [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);
    }
    
  • 但我也需要检查OAuth登录,如下所示:

    [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);
        }
    
        ...
    }
    

答案 1 :(得分:3)

您可以检查global.asax上的Application_AuthenticateRequest,是否可以检查请求是否与会话数据一起登录,并确定会话数据是否需要初始化,如您所说

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

    }   
}

或与

相同的结果
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

    }   
}    

答案 2 :(得分:2)

您可以在这两个地方调用您的代码:来自OnLoggedIn控件的Login事件以及会话启动时(使用Global.asax中的Session_Start事件),这将是用户数据的第一个请求。在那里,您可以检查用户是否已登录,如果是,请执行您需要的操作。

答案 3 :(得分:2)

虽然技术上登录与验证相同,但我有不同的心理模型。

在我看来,以下三件事是不同的问题:

  • 用户有/获得会话
  • 用户已通过身份验证
  • 用户已登录

对我来说,最后一个意思是:“为用户创建了一个会话,用户已经过身份验证,并且已经为经过身份验证的用户初始化了会话。”

使用此模型,用户可以在以下时间登录:

  • 用户登录登录页面,预先存在的会话为 用必要的用户数据初始化
  • 预先通过身份验证的用户访问该网站并进行新会话 为他/她创建并初始化

同样,用户在他/她的初始化会话被销毁时会被注销。

使用此模型意味着:

  • 您可以在Login.OnLoggedIn事件或Session_Start Global.asax事件中识别用户何时“登录”。当然,会话启动事件也会针对未经身份验证的用户触发,因此您需要在事件触发时验证用户是否已经过身份验证。
  • 您可以通过显式登出或在Global.asax中的Session_End事件中导致正确初始化的会话失败,在某种程度上可靠地判断用户何时“注销”。我说有点可靠,因为我认为当应用程序池在崩溃中回收或死亡时,不一定会触发Session_End事件。虽然我没有测试过,所以我可能错了。
  • 用户可以同时“登录”多次。至少在IE中,您可以从“文件”菜单中启动“新会话”。这启动了一个新的IE,它不与任何预先存在的IE窗口共享会话cookie。这意味着当用户访问该站点时,服务器将创建一个新会话,并且根据所使用的身份验证机制,这可能意味着他/她还必须再次进行身份验证。

它不会让你“列出所有当前登录的用户”开箱即用。你需要创建一种方法来跟踪我自己的想法。这或多或少都很难做到。特别是当您的应用程序在某种负载平衡环境中运行时,获取所有当前用户的列表可能会非常棘手。