【发布时间】:2014-09-12 03:50:34
【问题描述】:
我当前的会话管理器遇到了这个问题,当会话到期时,它不会注销用户。
在用户登录时,HttpContext.Current 是NULL 的随机间隔,导致站点产生许多错误。我尝试了几种技术在会话到期时将用户重定向到登录,但没有成功。
- 在
Global.asax下我正在使用Session_End可以尝试 调用LogOut方法,但这甚至在用户登录之前就被执行 在。 - 在
Global.asax下我添加了Application_AcquireRequestState,但遗憾的是,这让位于对SSO 服务的许多调用。此外,它永远不会在会话到期时重定向到登录。我用以下FormsAuthentication.RedirectToLoginPage()对其进行了测试;不走运。
我通过Lex Li "Why HttpContext.Current be null?" 找到了这个答案 - 它让我对我的问题可能有一些了解,即使我的应用程序没有使用后台线程,我的HttpContext.Current 又回来了一些随机请求的 null 并不总是发生。
会话管理器
public class SessionManager
{
private const string SessionKey = "AppSession";
private SessionManager()
{
GUID = new Guid();
FirstName = String.Empty;
LastName = String.Empty;
Email = String.Empty;
SessionExpiration = new DateTime();
}
// Gets the current session.
public static SessionManager Current
{
get
{
if(HttpContext.Current != null)
{
if (HttpContext.Current.Session[SessionKey] == null)
{
var model = new SessionManager();
HttpContext.Current.Session[SessionKey] = model;
}
return (SessionManager)HttpContext.Current.Session[SessionKey];
}
else
{
return null;
}
}
}
public static void LogOffUser()
{
//SSO is a seperate service, I need to stay insync.
var ssoAuth = new SSOAuth();
if(Current != null)
ssoAuth.SSOLogoffUser(Current.GUID);
FormsAuthentication.SignOut();
FormsAuthentication.RedirectToLoginPage();
}
public Guid GUID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public DateTime SessionExpiration { get; set; }
}
登录控制器
[HttpPost]
[AllowAnonymous]
public JsonResult Login(LoginViewModel user)
{
var ssoAuth = new SSOAuth();
var sessionObject = ssoAuth.SSOLoginUser(user.Email, user.Password);
if (sessionObject != null && sessionObject.SessionId != Guid.Empty)
{
SessionManager.Current.Email = sessionObject.UserId;
SessionManager.Current.GUID = sessionObject.SessionId;
SessionManager.Current.FirstName = sessionObject.FirstName;
SessionManager.Current.LastName = sessionObject.LastName;
SessionManager.Current.SessionExpiration = sessionObject.SessionExpiration;
//Grab difference in time to get session timeout in minutes.
var differenceInTime = SessionManager.Current.SessionExpiration - DateTime.Now;
Session.Timeout = differenceInTime.Minutes;
//Authenticate user
FormsAuthentication.SetAuthCookie(user.Email, false);
//We return JSON, Its an AJAX Call.
return Json(new
{
redirectUrl = "/Home.mvc/Home/Index",
isRedirect = true
});
}
return Json(new
{
redirectUrl = string.Empty,
isRedirect = false
});
}
【问题讨论】:
-
HttpContext.Current 永远不应为 null,除非在 Application_Start() 中,如果是,您必须在某处将其设置为 null。这只是不正常的情况。如果我是你,我会对 HttpContext 进行全局搜索并目视检查每个位置,以确保你没有在某处使用单个 = 而不是 ==。
-
您也不应该使用会话进行身份验证。会话不安全。另外,如果您的应用程序池被回收,您会丢失会话,但您的身份验证 cookie 仍然有效,因此事情将不同步。
-
@ErikFunkenbusch 谢谢你的意见,我现在正在全球搜索,我找不到任何设置
HttpContext,它正在使用但没有改变。另外,您对身份验证有何建议,我将用户信息存储在会话中,以确保其在全球范围内使用并与网络服务同步。 -
好吧,我会将大部分信息存储在 Auth Cookie 的用户数据部分。您已经在 auth cookie 中有用户 ID,因此不必保存,您可以将 cookie 的到期时间设置为与 SessionExpiration 相同,这样就不需要保存,只留下 FirstName、LastName 和指导。见danharman.net/2011/07/07/…
-
@ErikFunkenbusch 我正在阅读这篇文章,谢谢!请,为什么不将其发布为答案,如果我在该文章中的实施进展顺利,我可以接受您的答案。
标签: c# asp.net asp.net-mvc forms-authentication session-management