【问题标题】:ASP.NET Core 2.0 - users are logged out within an hourASP.NET Core 2.0 - 用户在一小时内注销
【发布时间】:2019-01-31 23:25:41
【问题描述】:

几天前,我将我的代码发布到“生产”环境中,只是为了进行测试。所以这个网站我一直在开发它是在线的。问题是,无论我对 cookie 设置进行什么更改。

我尝试将滑动过期时间更改为 true 和 false,两者都使用:

        options.ExpireTimeSpan = TimeSpan.FromDays(30);                
        options.Cookie.Expiration = TimeSpan.FromDays(30);

还将有效期设置为 1 年。 似乎没有任何效果。

这是我在 Startup.cs 中的设置:

public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<ForwardedHeadersOptions>(options =>
            {
                options.ForwardedHeaders = ForwardedHeaders.All;
                options.RequireHeaderSymmetry = false;
            });

            services.AddDbContext<IdentityDataContext>();

            services.AddIdentity<PinchilaIdentityUser, IdentityRole>()
                .AddEntityFrameworkStores<IdentityDataContext>()
                .AddUserManager<PinchilaUserManager>()
                .AddDefaultTokenProviders();
                services.Configure<SecurityStampValidatorOptions>(options => options.ValidationInterval = TimeSpan.FromSeconds(10));
                services.AddAuthentication()
                    .Services.ConfigureApplicationCookie(options =>
                    {
                        options.SlidingExpiration = true;
                        options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
                    });
}

        //COOKIE
            services.ConfigureApplicationCookie(options => {
                if (!String.IsNullOrEmpty(PinchilaSettings.Instance.CookieDomain))
                {
                    options.Cookie.Domain = PinchilaSettings.Instance.CookieDomain;
                }
                if (!String.IsNullOrEmpty(PinchilaSettings.Instance.CookieName))
                {
                    options.Cookie.Name = PinchilaSettings.Instance.CookieName;
                }
                options.AccessDeniedPath = new PathString("/error/default");
                options.ExpireTimeSpan = TimeSpan.FromDays(30);
                options.Cookie.Expiration = TimeSpan.FromDays(30);
            });

            var mvcBuilder = services.AddMvc();

            services.Configure<RazorViewEngineOptions>(options => {
                options.ViewLocationExpanders.Add(new ViewLocationExpander());
            });

            mvcBuilder.AddMvcOptions(o => {
                o.Filters.Add(typeof(GlobalExceptionFilter));
                o.Filters.Add(typeof(RuntimeStateFilter));
                o.Filters.Add(typeof(RouteLoggerFilter));
            });

            services.AddAntiforgery(options => {
                options.HeaderName = Utilities.CONSTANTS.REQUEST_VERIFICATION_HEADER_NAME;
                options.FormFieldName = Utilities.CONSTANTS.REQUEST_VERIFICATION_HEADER_NAME;
            });


            services.AddScoped<IViewRenderService, ViewRenderService>();
            services.AddLogging(loggingBuilder =>
            {
                var filter = new LoggingFilter();
                loggingBuilder.AddFilter(filter.Filter);
            });
        }

这是我的 AccountController 的登录部分:

[HttpPost]
[AllowAnonymous]
[PinchilaValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
    ViewData["ReturnUrl"] = returnUrl;
    if (ModelState.IsValid)
    {
        model.UserName = model.UserName.TrimSafe();
        model.Password = model.Password.TrimSafe();
        var user = await _userManager.FindByNameAsync(model.UserName);
        if (user != null)
        {
            var result = await _signInManager.PasswordSignInAsync(user, model.Password, model.RememberMe, lockoutOnFailure: true);
            if (result.Succeeded)
            {

                var cookie = HttpContext.Request.Cookies["theme"];
                if (cookie != null && !String.IsNullOrEmpty(cookie))
                {
                    Response.Cookies.Append("theme", "", new Microsoft.AspNetCore.Http.CookieOptions() { Expires = DateTime.UtcNow.AddDays(30) });
                }

                return RedirectToLocal(returnUrl);
            }
            if (result.IsLockedOut)
            {
                ModelState.AddModelError(string.Empty, "This account has been locked out for security reasons. Try again later.");
                return View(model);
            }
            else
            {
                ModelState.AddModelError(string.Empty, "Invalid login attempt");
                return View(model);
            }
        }
        else
        {
            ModelState.AddModelError(string.Empty, "Invalid login attempt");
        }
    }

    return View(model);

}

如果有人能给我一些不同的观点,我将不胜感激。

编辑:这是 cookie 在 Chrome 控制台上的样子:

【问题讨论】:

  • 使用浏览器的开发工具检查 cookie(以及设置 cookie 的 HTTP 标头)以查找任何问题。我建议您发布完整的 Set-Cookie 标头,这会有一些有用的线索。
  • 我刚刚用信息编辑了它。看起来有问题的是“notfirsttime”cookie 的值。
  • 你检查过IIS是否被回收了吗?如果有人回收您的 AppPoll 或 IIS,用户将失去他们的身份验证。
  • 我很困惑。您是说他们在一小时内注销,但您的到期时间是 30 分钟。即使使用滑动到期,如果用户在 30 分钟内处于非活动状态,他们也会被注销,当然,在绝对到期的情况下,无论如何,他们都会在 30 分钟内被注销。这两种情况都属于“一小时内”,那么这里的确切问题是什么?
  • 哦,我明白了。在大多数地方,您将其更改为 30 天。也许你错过了这一行:options.ExpireTimeSpan = TimeSpan.FromMinutes(30); in AddAuthentication

标签: asp.net-core asp.net-core-mvc asp.net-core-2.0 session-cookies


【解决方案1】:

感谢@TiagoBrenck 的评论,我开始在服务器端寻找答案。

我发现this post。请查看@dantey89 的答案。它解决了我的问题。

基本上,在 startup.cs 中,您需要在 ConfigureServices 方法中输入以下内容:

        public void ConfigureServices(IServiceCollection services)
    {

        var environment = services.BuildServiceProvider().GetRequiredService<IHostingEnvironment>();


        services.AddDataProtection()
                .SetApplicationName($"my-app-{environment.EnvironmentName}")
                .PersistKeysToFileSystem(new DirectoryInfo($@"{environment.ContentRootPath}\keys"));

       ...

    }

这将创建一个文件夹。它需要来自应用程序池的权限,否则会出现错误 500。

希望这对其他人有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-30
    • 2019-10-03
    • 1970-01-01
    • 2015-05-08
    相关资源
    最近更新 更多