ASP.net 年全球登录事件



当用户登录 ASP.net 网站时,有没有办法收到通知?

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

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

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

Global.asax具有全局"会话启动"通知的方式相同:

void Session_Start(object sender, EventArgs e) 
{
}

我假设某处有一个用户登录通知

void LoggedIn(object sender, EventArgs e)
{
}

奖金阅读

    登录
  • 页面上的登录事件 ASP.NET
  • 登录时运行自定义代码
  • MDSN Logon.OnLoggedIn 事件
  • 如果设置了"记住我",如何更新上次登录日期?

我认为你没有一个独特的地方来做到这一点。在我的情况下(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);
        }
        ...
    }
    

您可以在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
    }   
}    
您可以在

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

虽然从技术上讲,登录与身份验证相同,但我对此有不同的心理模型。

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

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

对我来说,其中最后一个意味着:"已为用户创建了会话,用户已通过身份验证,并且已为经过身份验证的用户初始化会话"。

使用此模型,用户可以在以下情况下登录:

  • 用户在登录页面上登录,并且预先存在的会话是使用必要的用户数据初始化
  • 经过预身份验证的用户访问站点,并且新会话是为他/她创建和初始化

同样,当用户的初始化会话被销毁时,用户将注销。

使用此模型将意味着:

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

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

相关内容

  • 没有找到相关文章

最新更新