ASP.Net Core Identity - Unable to stay logged in for more than 20 mintues - IIS 7.5

After deploying an ASP.Net Core app using Identity to Windows 2008 R2 (IIS 7.5) I cannot stay logged in after about 20 minutes of inactivity. I'm only using simple username / password authentication, no third party stuff.

This is not an issue on my Dev machine running VS 2017.

AccountController.cs

    public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
    {
        ViewData["ReturnUrl"] = returnUrl;
        if (ModelState.IsValid)
        {
            var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, true, lockoutOnFailure: false);
            if (result.Succeeded)
            {
                _logger.LogInformation(1, "User logged in.");
                return RedirectToLocal(returnUrl);
            }
            if (result.RequiresTwoFactor)
            {
                return RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
            }
            if (result.IsLockedOut)
            {
                _logger.LogWarning(2, "User account locked out.");
                return View("Lockout");
            }
            else
            {
                ModelState.AddModelError(string.Empty, "Invalid login attempt.");
                return View(model);
            }
        }

        return View(model);
    }

Any help kindly appreciated.

EDIT Here is my ConfigureServices method in it's entirety. It has an authorization policy which could be relevant.

        public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

        services.AddIdentity<ApplicationUser, ApplicationRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();


        services.AddAuthorization(options =>
        {
            options.AddPolicy("UserOnly", policy => policy.RequireRole("User"));
            options.AddPolicy("InstructorOnly", policy => policy.RequireRole("Instructor"));
            options.AddPolicy("AdminOnly", policy => policy.RequireRole("Admin"));
            options.AddPolicy("SystemManagerOnly", policy => policy.RequireRole("Manager"));

        });

        services.AddMvc(config =>
        {
            var policy = new AuthorizationPolicyBuilder()
                             .RequireAuthenticatedUser()
                             .Build();
            config.Filters.Add(new AuthorizeFilter(policy));
        });

        // Add application services.
        services.AddTransient<IEmailSender, AuthMessageSender>();
        services.AddTransient<ISmsSender, AuthMessageSender>();

        // Configure Identity
        services.Configure<IdentityOptions>(options =>
        {
            // Password settings
            options.Password.RequireDigit = true;
            options.Password.RequiredLength = 8;
            options.Password.RequireNonAlphanumeric = false;
            options.Password.RequireUppercase = false;
            options.Password.RequireLowercase = false;

            // Lockout settings
            options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(240);
            options.Lockout.MaxFailedAccessAttempts = 10;

            // Cookie settings
            options.Cookies.ApplicationCookie.ExpireTimeSpan = TimeSpan.FromDays(15);
            options.Cookies.ApplicationCookie.LoginPath = "/Account/LogIn";
            options.Cookies.ApplicationCookie.LogoutPath = "/Account/LogOff";
            options.Cookies.ApplicationCookie.SlidingExpiration = true;

            // User settings
            options.User.RequireUniqueEmail = true;



        });

        var appSettings = Configuration.GetSection("AppSettings");
        services.Configure<AppSettings>(appSettings);

        // Inject the ability to get current user
        services.AddTransient<IHttpContextAccessor, HttpContextAccessor>();
        // Inject the User access class
        services.AddTransient<UserResolverService>();


    }

Here is a screenshot of Chrome Dev Tools showing the response/request cookie. The Login page seems to send the correct cookie with a an expiration 15 days into the future. Subsequent pages are called using this cookie.

Login page redirect

enter image description here

Upvotes: 0

Views: 1618

Answers (2)

For some very strange reason I'm not seeing this problem anymore.

The only change I made to either config or code was configuring the IIS version log to enable cs(Cookie).

Thank for your assistance @Rohith Rajan

Upvotes: 0

Rohith
Rohith

Reputation: 5677

_signInManager.PasswordSignInAsync creates a cookie like this

Set-Cookie: .AspNetCore.Identity.Application=<cookie value>; expires=Fri, 14 Jul 2017 02:59:56 GMT; path=/; httponly

Next time when you make a request it should send this cookie if it is within the expires timestamp.Which will happen in your case

do you have some custom Authorize policy written ? Also in your application,Are you storing in anything in session and or any global variable and then checking it on login ?

20 minutes is the default IdleTimeout of IIS.Whenever any worker process is idle for more than 20 minutes,IIS shuts the process down .When the next request comes it automatically bring the worker process up.You can configure a higher timeout or an infinite timeout for the application pool

Upvotes: 1

Related Questions