繁体   English   中英

ASP.NET 核心6:设置session超时不起作用

[英]ASP.NET Core 6: Setting session timeout does not work

我正在尝试调整我的 .NET Core 6 项目以使用非默认的 session 超时。

按照 Microsoft.com 上的说明,我尝试将以下内容添加到我的 Program.cs 中:

//This should cause me to time out after 1 minute. It does not
builder.Services.AddDistributedMemoryCache();
builder.Services.AddSession(
    options => {
        options.Cookie.Name = ".MyWebsite.Session";
        options.IdleTimeout = TimeSpan.FromMinutes(1);
        options.Cookie.IsEssential = true;
    });

app.UseSession();

有什么我想念的吗? 我想增加 session 过期所需的时间。 根据上面的代码,当我登录程序时,我的 session 应该在 1 分钟后过期。 确实如此。 如果我将时间设置为 4 小时,则相同。 无论我使用什么设置,它似乎都迫使我在 20 分钟左右注销。

如果重要的话,该项目是从 .NET Core 3.1 迁移而来的。

以下是 Program.cs 文件中的完整代码:

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
var connectionString = builder.Configuration.GetConnectionString("MyConnection");
builder.Services.AddDbContext<DBContext>(options => options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddControllersWithViews();

builder.Services.AddDistributedMemoryCache();
builder.Services.AddSession(
    options => {
        options.Cookie.Name = ".MyWebsite.Session";
        options.IdleTimeout = TimeSpan.FromMinutes(1);
        options.Cookie.IsEssential = true;
    });

//Add JWT bearer and denied paths
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.LoginPath = "/Account/Unauthorized/";
        options.AccessDeniedPath = "/Account/Forbidden/";
    })
            .AddJwtBearer(x =>
            {
                x.RequireHttpsMetadata = false;
                x.SaveToken = true;
                x.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidateAudience = false,
                    ValidateIssuerSigningKey = true,
                    ValidIssuer = builder.Configuration["Jwt:Issuer"],
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("Jwt:Key"))
                };
            });

//GDPR compliance
builder.Services.Configure<CookiePolicyOptions>(options =>
{
    options.CheckConsentNeeded = context => true;
    options.MinimumSameSitePolicy = SameSiteMode.None;
});

builder.Services.ConfigureNonBreakingSameSiteCookies();

builder.Services.ConfigureApplicationCookie(options =>
{
    options.Events = new CookieAuthenticationEvents
    {
        OnRedirectToLogin = x =>
        {
            x.Response.Redirect("https://localhost:44329/Expired/Index/000");
            return Task.CompletedTask;
        }
    };
    options.ExpireTimeSpan = TimeSpan.FromDays(14);
    options.SlidingExpiration = true;
});

//define policy for different authorization
builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("AdminOnly", policy => policy.RequireRole("Administrator"));
    options.AddPolicy("UsersOnly", policy => policy.RequireRole("User", "Editor", "Administrator"));
    options.AddPolicy("RequireApprovedUser", policy => policy.Requirements.Add(new ApprovedUserRequirement(true)));
});

builder.Services.AddScoped<IAuthorizationHandler, ApprovedUserRequirementHandler>();

//Data Protection configuration
var keysFolder = Path.Combine(builder.Environment.ContentRootPath, "Keys");
builder.Services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo(keysFolder))
    .SetDefaultKeyLifetime(TimeSpan.FromDays(14));

builder.Services.AddIdentity<IdentityUser, IdentityRole>(options =>
{
    options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromHours(6);
    options.Lockout.MaxFailedAccessAttempts = 5;
    options.SignIn.RequireConfirmedAccount = true;
})
    .AddDefaultTokenProviders()
    .AddDefaultUI()
    .AddEntityFrameworkStores<DBContext>();

builder.Services.AddRazorPages();

builder.Services.AddScoped<IUserClaimsPrincipalFactory<IdentityUser>, UserClaimsPrincipalFactory<IdentityUser, IdentityRole>>();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}
app.Use(async (context, next) =>
{
    await next();
    if (context.Response.StatusCode >= 400)
    {
        context.Request.Path = "/Error/Index/" + context.Response.StatusCode;
        await next();
    }
});

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.UseSession();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
app.MapRazorPages();

app.Run();

使用 cookie 身份验证时,仅当调用HttpContext.Authentication.SignInAsync时我们传入一个IsPersistent设置为trueAuthenticationProperties实例时,才使用ExpireTimeSpan属性。

因此,您可能希望 cookie 在浏览器会话中持续存在。 只有在用户明确同意并在登录时使用“记住我”复选框或类似机制时,才应启用这种持久性。 代码如下:

// using Microsoft.AspNetCore.Authentication;

await HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme,
    new ClaimsPrincipal(claimsIdentity),
    new AuthenticationProperties
    {
        IsPersistent = true
    });

此外,您还可以设置绝对 cookie 过期时间。 以下代码片段创建一个持续 20 分钟的身份和相应的 cookie。 这会忽略之前配置的任何滑动过期设置。

// using Microsoft.AspNetCore.Authentication;

await HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme,
    new ClaimsPrincipal(claimsIdentity),
    new AuthenticationProperties
    {
        IsPersistent = true,
        ExpiresUtc = DateTime.UtcNow.AddMinutes(20)
    });

更多详细信息,请参阅持久性 cookies

好吧,我终于想通了。 事实证明,使用会话进行身份验证 cookies 是行不通的。 可能是我在其他地方做过的事情。

我使用以下命令强制我的 cookies 的生命周期为 1 分钟:

builder.Services.ConfigureApplicationCookie(options =>
{
    options.Cookie.Name = ".AspNetCore.Identity.Application";
    options.ExpireTimeSpan = TimeSpan.FromMinutes(1);
    options.Cookie.MaxAge = TimeSpan.FromMinutes(1);
    options.SlidingExpiration = true;
});

这里的关键是使用options.Cookie.MaxAge除了options.ExpireTimeSpan

现在给用户超过 20 多分钟的默认时间要容易得多。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM