Глобальное событие OnLoggedIn в 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)
{
}
Бонус Чтение
- Событие OnLoggedIn на странице входа ASP.NET
- Запустите пользовательский код при входе в систему
- Событие MDSN Logon.OnLoggedIn
- Как обновить дату последнего входа в систему, если установлено "Запомнить меня"?
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, но вы можете сделать это в своем
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); } ... }
Вы можете сделать проверку на 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
}
}
Вы можете назвать свой код в этих двух местах: OnLoggedIn
событие из Login
контроль, а также когда начинается сессия (используя Session_Start
событие в вашем Global.asax), так как это будет первый запрос с данными пользователя. Там вы можете проверить, вошел ли пользователь в систему и, если да, сделать то, что вам нужно.
Хотя технически вход в систему идентичен аутентификации, у меня другая ментальная модель этого.
На мой взгляд, три следующие вещи являются отдельными вопросами:
- Пользователь имеет / получает сеанс
- Пользователь аутентифицирован
- Пользователь вошел в систему
Для меня последнее из этих средств означает: "Для пользователя создан сеанс, пользователь прошел проверку подлинности, и сеанс был инициализирован для пользователя, прошедшего проверку".
Используя эту модель, пользователь может войти в систему, когда:
- Пользователь входит в систему на странице входа в систему, и существующий сеанс инициализируется необходимыми данными пользователя.
- Пользователь, прошедший предварительную проверку подлинности, заходит на сайт, и для него / нее создается и инициализируется новый сеанс
Точно так же пользователь выходит из системы, когда его / ее инициализированный сеанс уничтожен.
Использование этой модели будет означать:
- Вы можете определить, когда пользователь "входит в систему" либо в
Login.OnLoggedIn
событие илиSession_Start
событие вGlobal.asax
, Конечно, событие запуска сеанса также запускается для неаутентифицированных пользователей, поэтому вам нужно убедиться, что пользователь прошел аутентификацию при возникновении события. - Вы можете достаточно надежно сказать, когда пользователь "выходит из системы", либо явно выходя из системы, либо когда правильно инициализированный сеанс прерывается в
Session_End
событие в Global.asax. Я говорю достаточно надежно, потому что я думаю, что событие (-я) Session_End не обязательно будет запускаться, когда пул приложений перезапускается или умирает в случае сбоя. Хотя я не проверял это, поэтому я могу ошибаться. - Пользователь может быть одновременно "авторизован" несколько раз. По крайней мере, в IE вы можете начать "Новый сеанс" из меню "Файл". Это запускает новый IE, который не разделяет сеансовые куки с любыми существующими окнами IE. Это означает, что новый сеанс будет создаваться сервером, когда пользователь заходит на сайт, и в зависимости от используемого механизма аутентификации это может означать, что ему / ей также придется снова проходить аутентификацию.
Это не позволит вам "вывестисписок всех зарегистрированных пользователей" из коробки. Я думаю, вам нужно будет придумать способ самому отслеживать это. Это может мне более или менее сложно сделать. Особенно в том случае, когда ваше приложение работает в какой-то среде с балансировкой нагрузки, получить список всех текущих пользователей может быть сложно.