基于角色的身份验证Cookie的.NET Core动态过期

4

目前我们在项目的StartUp.cs中设置了Identity Cookie的过期时间。我们有一个标准超时时间,并希望根据已登录用户的角色动态设置超时时间。我想知道如何访问Claims角色以设置Cookie的过期时间。是否需要中间件?

基本上,我正在寻找:

services.AddIdentity<ApplicationUser, IdentityRole>(options => {

    options.Cookies.ApplicationCookie.ExpireTimeSpan = //BasedOnRole);

});

这也可以工作。
services.Configure<SecurityStampValidatorOptions>((options) => options.ValidationInterval = //BasedOnRole);
2个回答

8

身份验证的 Cookies 名称为 AspNetCore.Identity.Application,其 ExpireTimeSpanHandleSignInAsync 设置。

DateTimeOffset issuedUtc;
        if (signInContext.Properties.IssuedUtc.HasValue)
        {
            issuedUtc = signInContext.Properties.IssuedUtc.Value;
        }
        else
        {
            issuedUtc = Clock.UtcNow;
            signInContext.Properties.IssuedUtc = issuedUtc;
        }

        if (!signInContext.Properties.ExpiresUtc.HasValue)
        {
            signInContext.Properties.ExpiresUtc = issuedUtc.Add(Options.ExpireTimeSpan);
        }

        await Events.SigningIn(signInContext);

        if (signInContext.Properties.IsPersistent)
        {
            var expiresUtc = signInContext.Properties.ExpiresUtc ?? issuedUtc.Add(Options.ExpireTimeSpan);
            signInContext.CookieOptions.Expires = expiresUtc.ToUniversalTime();
        }

您可以通过重写HandleSignInAsync实现自己的CookieAuthenticationHandler
    public class CustomCookieAuthenticationHandler : CookieAuthenticationHandler
{
    public CustomCookieAuthenticationHandler(IOptionsMonitor<CookieAuthenticationOptions> options
        , ILoggerFactory logger
        , UrlEncoder encoder
        , ISystemClock clock) : base(options, logger, encoder, clock)
    {
    }

    protected override Task HandleSignInAsync(ClaimsPrincipal user, AuthenticationProperties properties)
    {
        if (user.Identity.Name == "test@outlook.com")
        {
            properties.ExpiresUtc = Clock.UtcNow.AddMinutes(15);
        }
        else
        {
            properties.ExpiresUtc = Clock.UtcNow.AddMinutes(35);
        }
        return base.HandleSignInAsync(user, properties);
    }
}

改变逻辑以设置 properties.ExpiresUtc

如果要替换内置的 CookieAuthenticationHandler,请尝试在 Startup 中进行替换。

            var descriptor =
            new ServiceDescriptor(
                typeof(CookieAuthenticationHandler),
                typeof(CustomCookieAuthenticationHandler),
                ServiceLifetime.Transient);
        services.Replace(descriptor);

这似乎是一个很好的答案。然而,在我的派生类中实现这段代码后,HandleSignInAsync从未被调用。我的.AspNetCore.Identity.Application cookie的默认过期时间是Epoch时间之前的时刻。 - Scott Clark
@ScottClark 这是我的测试 项目,请分享如何使用此项目重现您的问题。 - Edward
只是为了确认一下,CookieAuthenticationHandler.cs 中的 ReadCookieTicket 方法是否在每个请求中都被使用来验证身份验证 Cookie “AspNetCore.Identity.Application” 是否已过期?我知道大多数浏览器通常会删除过期的 Cookie,但是出于某种原因,如果用户仍在使用过期的 Cookie,我想确保 Identity 在幕后已经确保它不能被使用。谢谢! - eaglei22

-1

在启动时,您可以添加 cookies

services.ConfigureApplicationCookie(options =>
{
    options.AccessDeniedPath = "/Identity/Account/AccessDenied";
    options.Cookie.Name = "YourAppCookieName";
    options.Cookie.HttpOnly = true;
    options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
    options.LoginPath = "/Identity/Account/Login";
    // ReturnUrlParameter requires 
    //using Microsoft.AspNetCore.Authentication.Cookies;
    options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
    options.SlidingExpiration = true;
});


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接