【问题标题】:Global OnLoggedIn event in ASP.net?ASP.net 中的全局 OnLoggedIn 事件?
【发布时间】:2012-06-15 15:57:37
【问题描述】:

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

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

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

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

就像Global.asax 有一个全局的On Session Start 通知:

void Session_Start(object sender, EventArgs e) 
{
}

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

void LoggedIn(object sender, EventArgs e)
{
}

阅读奖励

【问题讨论】:

  • 我讨厌谷歌搜索我的问题(asp.net 全局 OnLoggedin 事件),结果是我自己的问题。

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


【解决方案1】:

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

【讨论】:

  • OnLoggedIn 用户浏览网站时不会调用事件。
  • 没错,这就是为什么我建议您在 Session_Start 中调用您需要的相同方法
  • 这似乎意味着没有全局“OnLoggedIn”事件。
  • 没有。如果您将代码放在一个类中,您将能够从两个地方调用它并解决您的问题。
  • 还有其他问题吗?我知道用户可以保持登录状态,即使会话结束(即应用程序池回收)。
【解决方案2】:

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

    }   
}    

【讨论】:

  • 我无法真正与Forms 身份验证或表单cookie 的使用相关联。如果我不使用 Forms 身份验证,或者没有 cookie,他们仍然可以登录。
  • @IanBoyd 如果你看到我有和其他检查方式......使用HttpContext.Current.User.Identity.IsAuthenticated,第一个更快。
  • 我对@9​​87654326@ 做了something 错误,它被用户调用了 7 次。
  • @IanBoyd 对任何 asp.net 资源的每个请求都会调用以检查是否需要身份验证,您可以再检查它是什么文件,如果是 aspx,或者处理程序让它做剩下的。使用HttpContext.Current.Request.PathSystem.IO.Path.GetExtension(cTheFile) 检查扩展名- 抱歉必须离开电脑,我会在几个小时后返回。希望这会有所帮助
【解决方案3】:

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

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

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

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

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

  • 用户在登录页面登录,预先存在的会话是 用必要的用户数据初始化
  • 预认证的用户来到站点并且新的会话是 为他/她创建和初始化

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

使用这个模型意味着:

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

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

【讨论】:

    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-15
      • 1970-01-01
      • 1970-01-01
      • 2016-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多