【发布时间】:2016-10-21 02:35:27
【问题描述】:
我的网站不断失去其会话状态并让用户退出,我不知道为什么。
我有一个操作过滤器,它会尝试检查 UserSession 是否仍然存在,如果不存在,它会检查用户是否经过身份验证,并尝试根据经过身份验证的用户 ID 恢复用户会话。
如果用户未通过身份验证,我会将他们重定向到登录页面。我还有一些代码可以检查它是否是 ajax 请求并手动将状态码设置为 403,以便我的 ajax 调用可以识别此状态并在 javascript 端进行重定向。
这是我的动作过滤器:
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
SecuredController baseController = filterContext.Controller as SecuredController;
// Check if the session is available
if (filterContext.HttpContext.Session["UserSession"] == null)
{
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
filterContext.Result = new JsonResult
{
Data = new { Error = "Unavailable", Url = "~/Account/Login" },
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
return;
}
if (!string.IsNullOrEmpty(HttpContext.Current.Request.RawUrl))
{
string returnUrl = HttpUtility.UrlEncode(HttpContext.Current.Request.RawUrl);
HttpContext.Current.Response.Redirect("~/Account/Login?returnUrl=" + returnUrl);
}
else
{
HttpContext.Current.Response.Redirect("~/Account/Login");
}
}
string userId = filterContext.HttpContext.User.Identity.GetUserId();
Web.Helpers.Common common = new Helpers.Common();
UserSession userSession = common.GetUserSession(userId);
filterContext.HttpContext.Session["UserSession"] = userSession;
}
// Set the Current user to the session variable
baseController.CurrentUser = (UserSession)filterContext.HttpContext.Session["UserSession"];
// Continue executing the relevant action
base.OnActionExecuting(filterContext);
}
这是我的 Javascript 代码:
$.ajax({
type: method,
url: rootUrl + serviceUrl,
async: aSync,
data: dataParameters,
cache: false,
beforeSend: function () {
if (targetProgressContainer === undefined) {
return;
}
if ($(targetProgressContainer).length === 0) {
console.log('The Progress Container Div "' + targetProgressContainer + ' could not be found!');
return;
}
$(targetProgressContainer).html($(_progressContainer).html());
},
statusCode:{
403: function (data) {
window.top.location.href = sessionEndedUrl;
}
},
success: function (responseData, status, xhr) {
successCallback(responseData);
},
error: function (request, textStatus, errorThrown) {
errorCallback(request, textStatus, errorThrown);
}
});
这是我的 Startup.ConfigureAuth 方法:
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
// Configure the sign in cookie
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
// Enables the application to validate the security stamp when the user logs in.
// This is a security feature which is used when you change a password or add an external login to your account.
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
},
SlidingExpiration =true,
ExpireTimeSpan = TimeSpan.FromDays(30)
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process.
app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));
我添加了一些规则来确保用户 url 是完整的域
<rules>
<rule name="Add www prefix to example.com domain" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^example\.com" />
</conditions>
<action type="Redirect" url="http://www.example.com/{R:1}" />
</rule>
</rules>
有人有什么想法吗?
【问题讨论】:
-
身份验证会话即将到期,因为身份验证票已过期?
-
嘿Hakunamatata,我在验证代码中添加了。真的不明白为什么它会过期。
-
你的逻辑看起来不错。唯一的问题是默认会话超时为 20 分钟,因此如果 20 分钟内没有活动,您的会话将过期。在配置中增加这个值。如果没有要处理的请求,IIS 还将根据空闲超时值回收应用程序池。也增加这个值。
-
它是如此零星,有一段时间我会很好地浏览网站,但突然间它把我踢了出去。其他时候我登录,甚至没有导航 2-3 页,它把我踢了出去。我真的很茫然。
-
会不会是因为服务器配置不好?我们曾经在我们的工作场所有过类似的经历,我很确定这个问题只出现在一个开发服务器中。如果你有幸在另一台服务器上检查它,你至少可以减轻一些痛苦。
标签: javascript asp.net ajax session