简体   繁体   English

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

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

This project is still in development and works perfectly on my dev laptop, however, when I publish to my shared hosting web server (Winserve), this is when the functionality breaks.该项目仍在开发中,在我的开发笔记本电脑上运行良好,但是,当我发布到我的共享托管 Web 服务器 (Winserve) 时,功能就会中断。

Side note: I'm sure this was working fine a couple of weeks ago, but I could be wrong as I've spent most of my time running this on my dev laptop.旁注:我确定这在几周前运行良好,但我可能是错的,因为我大部分时间都在我的开发笔记本电脑上运行它。

I have a basic asp.net Core 3.1 web application.我有一个基本的 asp.net Core 3.1 Web 应用程序。 I've added Cookie and Authentication information to the Configure() and ConfigureServices() sections in my startup.cs file.我已将 Cookie 和身份验证信息添加到我的 startup.cs 文件中的 Configure() 和 ConfigureServices() 部分。

I can log in to the application in PROD and my auth cookie seems to be set correctly, it's grabbing the roles from the db correctly and adding the relevant claims etc. and giving the user the correct Roles.我可以登录到 PROD 中的应用程序,我的 auth cookie 似乎设置正确,它正确地从数据库中获取角色并添加相关声明等,并为用户提供正确的角色。 I know this because the UI changes based on whether or not User.Identity.IsAuthenticated = true and whether or not User.IsInRole("Some Role") etc.我知道这是因为 UI 会根据 User.Identity.IsAuthenticated = true 以及 User.IsInRole("Some Role") 等是否发生变化。

However, after a (not consistant) period of time, usually around 30-40 seconds, when I navigate to a page (Controller/Action) that needs the user to be authenticated (qualified with [Authorize]), I get redirected back to the Login page!但是,经过一段(不一致的)时间后,通常大约 30-40 秒,当我导航到需要对用户进行身份验证(具有 [Authorize] 资格)的页面(控制器/操作)时,我被重定向回登录页面! This isn't just a redirect though, the user has been either signed out or the cookie no longer works.但这不仅仅是重定向,用户已被注销或 cookie 不再有效。 I've tried once every 5 seconds for about 30 seconds after this happens to get back to the 'Authorized' URL and every time I get pushed back to the Login page.我每 5 秒尝试一次,持续大约 30 秒,在这碰巧返回“授权”URL 并且每次我被推回登录页面时。

Within that time (before the 30-40 seconds), I can navigate to secured pages to my heart's content.在那段时间内(在 30-40 秒之前),我可以导航到受保护的页面,找到我的心声。 All different pages and either one straight after the other, or leave a few second gap between navigations and it still works, right up until it doesn't!所有不同的页面,要么一个接一个,要么在导航之间留几秒钟的间隔,它仍然可以工作,直到它不工作为止!

Also, I've checked the Cookies in the browser inspector and the Cookie is definitely getting created, with a default expiry date of around 14 days I think it is.此外,我已经在浏览器检查器中检查了 Cookie,并且肯定会创建 Cookie,我认为它的默认到期日期约为 14 天。 But it's way in the future regardless.但无论如何,这都是未来的道路。

Here is my Startup.cs这是我的 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?}");
            });

        }

Here is my Login and logout methods in my HomeController...这是我的 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();
        }

And the methods they call...他们调用的方法......

   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");
        }

Example Cotroller that you need to be authorised to be able to access...您需要获得授权才能访问的示例控制器...

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

I found the solution to my problem thanks to @weichch感谢@weichch,我找到了问题的解决方案

There was an AppPool size limit set by my cheap hosting provider which was 200MB我的廉价托管服务提供商设置了 200MB 的 AppPool 大小限制

My app, when loaded through IIS Express through VS, got to around 160-180MB and then fairly quickly, (just by doing a few things in my admin section for example), went above 200MB, but then sat around 220-230MB and didn't really move (so it's not a memeory leak problem).我的应用程序,当通过 VS 通过 IIS Express 加载时,达到 160-180MB 左右,然后相当快,(例如,只需在我的管理部分做一些事情),超过 200MB,但然后坐在 220-230MB 左右,并没有并没有真正移动(所以这不是内存泄漏问题)。

I upgraded my plan with my provider to one where the AppPool can go to 512MB, and this completely solved the problem.我与我的提供商将我的计划升级到 AppPool 可以达到 512MB 的计划,这完全解决了问题。 It's been working fine ever since.从那以后它一直运行良好。

Thanks everyone 👍谢谢大家👍

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

相关问题 .net core 3.1 身份在使用身份短时间内不断强制用户登录 - .net core 3.1 identity keeps forcing user to log in after short time using Identity Asp.Net Core 3.1 Cookie 身份验证循环到登录页面 - Asp.Net Core 3.1 Cookie Authentication loop to login page Cookie 认证失败 ASP.NET Core 3.1 - Cookie Authentication Fails ASP.NET Core 3.1 在 Web 部署发布到远程 IIS 后,ASP.NET Core 3.1 身份持久化 cookie 身份验证仍然失败 - ASP.NET Core 3.1 identity persist cookie authentication after web deploy publish to remote IIS still fails Asp.Net Core 2.0 Cookie身份验证在时间之前到期 - Asp.Net Core 2.0 Cookie Authentication Expires Before Time 在 cookie 中存储 JWT 令牌后如何打破该 cookie 并在 ASP.NET Core 3.1 中获取信息 - After store JWT token in cookie how to break that cookie and get information in ASP.NET Core 3.1 .Net核心身份验证设置cookie路径后失败 - .Net core authentication fails after setting cookie path .Net Core 3.1 - Google Auth Cookie 不持久 - .Net Core 3.1 - Google Auth Cookie Not Persisting 如何在 .Net Core 3.1 Identity Server 4 中更改持久性 Cookie 过期时间 - How to Change Persistent Cookie Expiration Time in .Net Core 3.1 Identity Server 4 基于 IPAddress 和客户端设备在 asp.net 核心 3.1 身份中设置 Cookie Expiration 时间跨度 - Set Cookie Expiration time span based on IPAddress and client device in asp.net core 3.1 identity
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM