我正在将Identityserver4与ASP.NET Identity一起使用,并将cookie配置为SlidingExpiration = true和ExpireTimeSpan = 20分钟。我想在用户即将超时时向用户提供警告,因此尝试访问Cookie中的“ .expiry”值。
到目前为止,我已经能够使用下面的Razor代码读取 到期时间。 但是,这在用户刷新票证时无法读取正确的到期时间。根据{{3}},如果滑动用户在获得票证后10分钟或更长时间(> = ExpireTimeSpan的50%)刷新页面,则应该为我的用户提供一张新票证。这样做很好,但是这样做的话,下面的代码提供了旧的到期时间,直到用户第二次刷新页面为止!
@(DateTime.Parse(((await Context.AuthenticateAsync()).Properties.Items)[".expires"]))
我想知道的是,如何在提供新票证时生成的页面上获得正确的到期时间?
答案 0 :(得分:1)
这里的问题是在呈现页面后进行续订-新属性仅在后续请求中可用。
一个选项可能是使用客户端代码轮询最近的到期时间,但这会成为保持活动状态,这可能不是您想要的。
为缓解上述问题,您可以创建自己的cookie中间件实现(所有源代码都在github上)并自定义滑动到期逻辑(CheckForRefresh和RequestRefresh)。您还可以将新的到期时间添加到HttpContext中,从而使它更早可用于您的控制器代码。
源代码:https://github.com/aspnet/Security/tree/master/src/Microsoft.AspNetCore.Authentication.Cookies
您只需要创建自己的CookieAuthenticationHandler版本(少于500行代码)和您自己的注册助手(请查看CookieExtensions):
public static AuthenticationBuilder AddCustomCookie(this AuthenticationBuilder builder, string authenticationScheme, string displayName, Action<CookieAuthenticationOptions> configureOptions)
{
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<CookieAuthenticationOptions>, PostConfigureCookieAuthenticationOptions>());
return builder.AddScheme<CookieAuthenticationOptions, CustomCookieAuthenticationHandler>(authenticationScheme, displayName, configureOptions);
}
答案 1 :(得分:0)
我已经解决了我的问题,我不太喜欢这个解决方案,因为它很hacky 。它确实可以工作,所以我将其发布在这里以防万一。如果有人可以帮助我理解更好的解决方案,我将不胜感激,如果有的话,我会编辑此答案或删除它,以取而代之。
我以与问题基本相同的方式获得身份验证凭单的有效期,然后如果剩余的ExpireTimeSpan设置少于50%,我认为它会续订(可能有点冒险,但到目前为止,这是我最好的)已经管理好了)。我用它来计算到超时之前剩余的假定秒数,然后在决定何时向用户显示警告时使用此值。
在剃刀顶部(部分):
@using Microsoft.AspNetCore.Authentication;
我代码的重要部分(可以提出改进建议):
secondsRemaining = "@(DateTime.Parse(((await AuthenticationHttpContextExtensions
.AuthenticateAsync(Context))
.Properties
.Items)[".expires"])
.Subtract(DateTime.Now)
.TotalSeconds)";
// If secondsRemaining is less than half the expiry timespan then assume it will be re-issued
if (secondsRemaining < timeoutSeconds / 2) {
secondsRemaining = timeoutSeconds;
}