5

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

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

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

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

Global.asax具有全局On Session Start通知的方式相同:

void Session_Start(object sender, EventArgs e) 
{
}

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

void LoggedIn(object sender, EventArgs e)
{
}

奖金阅读

4

4 回答 4

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 应用程序模板,但Login.OnLoggedIn如果您使用的是 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);
    }
    
  • 但我也需要检查 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);
        }
    
        ...
    }
    
于 2012-10-25T08:28:15.373 回答
3

您可以Application_AuthenticateRequest在 global.asax 上进行检查,这是您可以检查请求是否与会话数据一起登录的地方,并决定会话数据是否需要按照您所说的进行初始化。

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

    }   
}    
于 2012-06-12T18:11:16.090 回答
2

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

于 2012-06-12T18:07:05.587 回答
2

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

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

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

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

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

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

同样,当他/她的初始化会话被破坏时,用户将被注销。

使用此模型将意味着:

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

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

于 2012-06-14T10:14:32.153 回答