繁体   English   中英

.NET Core 3.1 身份验证 Cookie 在很短的时间内丢失

[英].NET Core 3.1 Authentication Cookie Lost After Very Short Time

该项目仍在开发中,在我的开发笔记本电脑上运行良好,但是,当我发布到我的共享托管 Web 服务器 (Winserve) 时,功能就会中断。

旁注:我确定这在几周前运行良好,但我可能是错的,因为我大部分时间都在我的开发笔记本电脑上运行它。

我有一个基本的 asp.net Core 3.1 Web 应用程序。 我已将 Cookie 和身份验证信息添加到我的 startup.cs 文件中的 Configure() 和 ConfigureServices() 部分。

我可以登录到 PROD 中的应用程序,我的 auth cookie 似乎设置正确,它正确地从数据库中获取角色并添加相关声明等,并为用户提供正确的角色。 我知道这是因为 UI 会根据 User.Identity.IsAuthenticated = true 以及 User.IsInRole("Some Role") 等是否发生变化。

但是,经过一段(不一致的)时间后,通常大约 30-40 秒,当我导航到需要对用户进行身份验证(具有 [Authorize] 资格)的页面(控制器/操作)时,我被重定向回登录页面! 但这不仅仅是重定向,用户已被注销或 cookie 不再有效。 我每 5 秒尝试一次,持续大约 30 秒,在这碰巧返回“授权”URL 并且每次我被推回登录页面时。

在那段时间内(在 30-40 秒之前),我可以导航到受保护的页面,找到我的心声。 所有不同的页面,要么一个接一个,要么在导航之间留几秒钟的间隔,它仍然可以工作,直到它不工作为止!

此外,我已经在浏览器检查器中检查了 Cookie,并且肯定会创建 Cookie,我认为它的默认到期日期约为 14 天。 但无论如何,这都是未来的道路。

这是我的 Startup.cs

public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews().AddRazorRuntimeCompilation().AddNewtonsoftJson();

            services.AddControllers().AddNewtonsoftJson();

            services.AddDistributedMemoryCache();

            services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                    .AddCookie(options =>
                                {
                                    options.LoginPath = "/Login";
                                });

            services.AddAuthorization();

            services.AddSession(options =>
            {
                options.IdleTimeout = TimeSpan.FromMinutes(30);
                options.Cookie.HttpOnly = true;
                options.Cookie.IsEssential = true;
            });

            services.AddMvc().AddNewtonsoftJson();

            services.AddRazorPages().AddNewtonsoftJson();

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseRouting();

            app.UseSession();

            app.UseAuthentication();

            app.UseAuthorization();

            app.UseHttpsRedirection();

            app.UseStaticFiles();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "areas",
                    pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

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

        }

这是我的 HomeController 中的登录和注销方法...

public IActionResult Login(LoginViewModel model)
        {
            if (string.IsNullOrEmpty(model.Username) || string.IsNullOrEmpty(model.Password)) { model.Errors.Add("Must provide a Username & Password"); return View(model); }
            var _user = _authenticationBusinessService.AuthenticateUser(model.Username, model.Password);
            if (_user != null && _user.Id > 0) { return SignUserIn(model, _user); }
            else { model.Errors.Add("We're unable to authenticate you with the credentials provided"); }
            return View(model);
        }

        public IActionResult SignOut()
        {
            return SignUserOut();
        }

他们调用的方法......

   private IActionResult SignUserIn(LoginViewModel model, UserDTO user)
        {
            var _claims = new List<Claim>
            {
                //User identity information
                new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
                new Claim(ClaimTypes.Name, user.Id.ToString()),
                new Claim("FirstName", user.Person.FirstName),
                new Claim("Surname", user.Person.Surname)
            };
            //Roles/Permissions
            _claims.AddRange(user.UserPermissionMaps.Select(x => new Claim(ClaimTypes.Role, x.Permission.Description)));

            var _claimsIdenity = new ClaimsIdentity(_claims, CookieAuthenticationDefaults.AuthenticationScheme);
            var _authProperties = new AuthenticationProperties() { IsPersistent = true, AllowRefresh = true };
            var _claimsPrincipal = new ClaimsPrincipal(_claimsIdenity);
            HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, _claimsPrincipal, _authProperties);

            if (string.IsNullOrEmpty(model.ReturnURL))
            {
                model.ReturnURL = "/";
            }
            return Redirect(model.ReturnURL);
        }
        private IActionResult SignUserOut()
        {
            HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
            HttpContext.Session.Clear();
            return RedirectToAction("Index");
        }

您需要获得授权才能访问的示例控制器...

 [Area("Admin")]
    public class HomeController : Controller
    {
        [Authorize]
        public IActionResult Index()
        {
            return View();
        }
    }

感谢@weichch,我找到了问题的解决方案

我的廉价托管服务提供商设置了 200MB 的 AppPool 大小限制

我的应用程序,当通过 VS 通过 IIS Express 加载时,达到 160-180MB 左右,然后相当快,(例如,只需在我的管理部分做一些事情),超过 200MB,但然后坐在 220-230MB 左右,并没有并没有真正移动(所以这不是内存泄漏问题)。

我与我的提供商将我的计划升级到 AppPool 可以达到 512MB 的计划,这完全解决了问题。 从那以后它一直运行良好。

谢谢大家👍

暂无
暂无

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

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