当用户使用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)
{
}
答案 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
事件中识别用户何时“登录”。当然,会话启动事件也会针对未经身份验证的用户触发,因此您需要在事件触发时验证用户是否已经过身份验证。Session_End
事件中导致正确初始化的会话失败,在某种程度上可靠地判断用户何时“注销”。我说有点可靠,因为我认为当应用程序池在崩溃中回收或死亡时,不一定会触发Session_End事件。虽然我没有测试过,所以我可能错了。它不会让你“列出所有当前登录的用户”开箱即用。你需要创建一种方法来跟踪我自己的想法。这或多或少都很难做到。特别是当您的应用程序在某种负载平衡环境中运行时,获取所有当前用户的列表可能会非常棘手。