我正在使用ASP.Net身份验证来控制我的应用程序授权,我需要在指定的非活动分钟后终止用户会话,我试图通过以下方法来实现这一点
public void ConfigureAuth(IAppBuilder app) {
app.CreatePerOwinContext<UserStore>(() => new UserStore());
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.UseCookieAuthentication(new CookieAuthenticationOptions {
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/login"),
LogoutPath = new PathString("/logout"),
CookieDomain = ConfigurationManager.AppSettings["CookieDomain"],
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(2),
regenerateIdentity: (manager, user) => manager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie)
)
},
SlidingExpiration = true,
});
}
我也尝试过这种方法
app.UseCookieAuthentication(new CookieAuthenticationOptions {
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/login"),
LogoutPath = new PathString("/logout"),
CookieDomain = ConfigurationManager.AppSettings["CookieDomain"],
ExpireTimeSpan = TimeSpan.FromMinutes(2),
SlidingExpiration = true,
});
使用这些提示,用户cookie会话在2分钟后过期,无论用户是否在站点上处于活动状态。我在文档中读到,通过设置SlidingExpiration = true
,cookie将在ExpireTimeSpan中途的任何请求中重新发出。例如,如果用户登录并在16分钟后发出第二个请求,则cookie将再次发出30分钟。如果用户登录,然后在31分钟后发出第二个请求,则系统将提示用户登录。
我不知道为什么它不工作,有什么想法吗?
发布于 2018-12-06 15:44:29
需要说明的是:在请求刷新之前,CookieHandler正在检查cookie过期之前的剩余时间是否小于发出后所经过的时间(即它已超过一半)。这在Microsoft.AspNetCore.Authentication.Cookies的动态链接库中。
就我个人而言,我更希望有一个选项来更改流逝的百分比。当你为更安全的应用程序使用非常小的超时时间(15分钟或更短)时,让用户在7分钟不活动后超时,因为cookie在他们活动的前6分钟内从未刷新,这是相当恼人的。
也许会添加一个选项来使用剩余的timespan检查常量。例如,当cookie剩余的时间少于{TimeSpan}时,发出刷新请求。
private void CheckForRefresh(AuthenticationTicket ticket)
{
DateTimeOffset utcNow = this.get_Clock().get_UtcNow();
DateTimeOffset? issuedUtc = ticket.get_Properties().get_IssuedUtc();
DateTimeOffset? expiresUtc = ticket.get_Properties().get_ExpiresUtc();
bool? allowRefresh = ticket.get_Properties().get_AllowRefresh();
bool flag = !allowRefresh.HasValue || allowRefresh.GetValueOrDefault();
if (((!issuedUtc.HasValue || !expiresUtc.HasValue ? 0 : (this.get_Options().SlidingExpiration ? 1 : 0)) & (flag ? 1 : 0)) == 0)
return;
TimeSpan timeSpan = utcNow.Subtract(issuedUtc.Value);
if (!(expiresUtc.Value.Subtract(utcNow) < timeSpan))
return;
this.RequestRefresh(ticket);
}
发布于 2020-06-17 09:18:25
我怀疑问题在于,尽管SlidingExpiration为真,但刷新行为被抑制了。查看片名源代码、CookieAuthenticationHandler类、AuthenticateCoreAsync()方法,我们可以看到:
bool? allowRefresh = ticket.Properties.AllowRefresh;
if (issuedUtc != null && expiresUtc != null && Options.SlidingExpiration
&& (!allowRefresh.HasValue || allowRefresh.Value))
{
TimeSpan timeElapsed = currentUtc.Subtract(issuedUtc.Value);
TimeSpan timeRemaining = expiresUtc.Value.Subtract(currentUtc);
if (timeRemaining < timeElapsed)
{
_shouldRenew = true;
_renewIssuedUtc = currentUtc;
TimeSpan timeSpan = expiresUtc.Value.Subtract(issuedUtc.Value);
_renewExpiresUtc = currentUtc.Add(timeSpan);
}
}
即,只有当ticket.Properties.AllowRefresh为null或true时,才会发生刷新,并且根据您使用的中间件的不同,可能会将其设置为false。例如,在OpenIdConnectAuthenticationHandler和WsFederationAuthenticationHandler中,我们有...
private ClaimsPrincipal ValidateToken(...)
{
...
if (Options.UseTokenLifetime)
{
// Override any session persistence to match the token lifetime.
DateTime issued = jwt.ValidFrom;
if (issued != DateTime.MinValue)
{
properties.IssuedUtc = issued.ToUniversalTime();
}
DateTime expires = jwt.ValidTo;
if (expires != DateTime.MinValue)
{
properties.ExpiresUtc = expires.ToUniversalTime();
}
properties.AllowRefresh = false;
}
}
请注意,UseTokenLifetime缺省为true。因此,默认行为是使用我们从IdP服务器获得的authentiaction令牌的过期时间,并在到达该过期时间时结束会话,而不管用户是否处于活动状态。
https://stackoverflow.com/questions/38983173
复制