Cookie 持久性在 OWIN 身份验证中不起作用
Cookie persistence not working in OWIN authentication
我正在开发一个使用 OWIN 身份验证系统(Microsoft.Owin v4.1.0
通过 NuGet)的 MVC5 网站。我根据数据库验证用户的登录凭据,然后使用 OWIN IAuthenticationManager
登录。这是相关代码:
using Microsoft.Owin.Security;
public class AuthManager : IAuthManager
{
private readonly IAuthenticationManager AuthenticationManager;
public AuthManager()
{
this.AuthenticationManager = HttpContext.Current.GetOwinContext().Authentication;
}
public void SignIn(AppUserState appUserState, bool rememberMe)
{
AuthenticationProperties authenticationProperties = new AuthenticationProperties()
{
AllowRefresh = true,
IsPersistent = rememberMe,
ExpiresUtc = DateTime.UtcNow.AddDays(14),
IssuedUtc = DateTime.UtcNow
};
List<Claim> claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.NameIdentifier, appUserState.EmailAddress));
claims.Add(new Claim(ClaimTypes.Name, appUserState.Name));
claims.Add(new Claim("userState", appUserState.ToString()));
ClaimsIdentity identity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);
this.AuthenticationManager.SignIn(authenticationProperties, identity);
}
}
登录过程有效,但持久性无效。大约 30-60 分钟后,会话总是结束,尽管 IsPersistent
被设置为 true
。当我在调试器中单步执行并检查 authenticationProperties
对象时,我可以看到 IsPersistent
确实为真。
我在网上读到,这是一个标志,它决定您的应用程序是否应该让您的用户保持登录状态,即使用户没有积极使用该网站。然而,用户的会话总是结束。
我认识到的一件事是 AuthenticationProperties
class 里面有一个字典对象:
当我打开字典时,我可以看到有一个标有 .persistent
的键,它的值为空。我尝试将此值设置为 True
(以复制 .refresh
键的行为)-但这根本没有效果。
我认为上述问题与问题无关,但我认为我应该分享我已经进行的调查。
如何防止用户自动退出?
持久性 cookie 只是不会在您关闭浏览器会话时被清除,它们仍然会过期。将 CookieAuthenticationOptions
中的 ExpireTimeSpan
设置得更长一些。
事实证明这与 cookie 过期时间无关。我尝试将 ExpireTimeSpan
设置为 14 天(作为测试),但没有任何区别 - 我仍然自动注销。
但是我正在查看相同的方法 (ConfigureAuth
) 并看到我有以下代码:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
ExpireTimeSpan = new TimeSpan(14, 0, 0, 0, 0),
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
});
作为测试,我将 validateInterval: TimeSpan.FromMinutes(30),
设置为 3000 分钟。 30 分钟后我不再被注销。所以我的会话结束的原因是因为显然对 SecurityStampValidator.OnValidateIdentity
的调用返回当前用户未经授权!
我正在开发一个使用 OWIN 身份验证系统(Microsoft.Owin v4.1.0
通过 NuGet)的 MVC5 网站。我根据数据库验证用户的登录凭据,然后使用 OWIN IAuthenticationManager
登录。这是相关代码:
using Microsoft.Owin.Security;
public class AuthManager : IAuthManager
{
private readonly IAuthenticationManager AuthenticationManager;
public AuthManager()
{
this.AuthenticationManager = HttpContext.Current.GetOwinContext().Authentication;
}
public void SignIn(AppUserState appUserState, bool rememberMe)
{
AuthenticationProperties authenticationProperties = new AuthenticationProperties()
{
AllowRefresh = true,
IsPersistent = rememberMe,
ExpiresUtc = DateTime.UtcNow.AddDays(14),
IssuedUtc = DateTime.UtcNow
};
List<Claim> claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.NameIdentifier, appUserState.EmailAddress));
claims.Add(new Claim(ClaimTypes.Name, appUserState.Name));
claims.Add(new Claim("userState", appUserState.ToString()));
ClaimsIdentity identity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);
this.AuthenticationManager.SignIn(authenticationProperties, identity);
}
}
登录过程有效,但持久性无效。大约 30-60 分钟后,会话总是结束,尽管 IsPersistent
被设置为 true
。当我在调试器中单步执行并检查 authenticationProperties
对象时,我可以看到 IsPersistent
确实为真。
我在网上读到,这是一个标志,它决定您的应用程序是否应该让您的用户保持登录状态,即使用户没有积极使用该网站。然而,用户的会话总是结束。
我认识到的一件事是 AuthenticationProperties
class 里面有一个字典对象:
当我打开字典时,我可以看到有一个标有 .persistent
的键,它的值为空。我尝试将此值设置为 True
(以复制 .refresh
键的行为)-但这根本没有效果。
我认为上述问题与问题无关,但我认为我应该分享我已经进行的调查。
如何防止用户自动退出?
持久性 cookie 只是不会在您关闭浏览器会话时被清除,它们仍然会过期。将 CookieAuthenticationOptions
中的 ExpireTimeSpan
设置得更长一些。
事实证明这与 cookie 过期时间无关。我尝试将 ExpireTimeSpan
设置为 14 天(作为测试),但没有任何区别 - 我仍然自动注销。
但是我正在查看相同的方法 (ConfigureAuth
) 并看到我有以下代码:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
ExpireTimeSpan = new TimeSpan(14, 0, 0, 0, 0),
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
});
作为测试,我将 validateInterval: TimeSpan.FromMinutes(30),
设置为 3000 分钟。 30 分钟后我不再被注销。所以我的会话结束的原因是因为显然对 SecurityStampValidator.OnValidateIdentity
的调用返回当前用户未经授权!