ASP.NET Core 1.0 – MVC 6 – Cookie Expiration

UPDATE:

It is definitely not a bug in RC1. The cookie settings are working with the default UserManager and UserStore, so it must be something related to my UserManager/UserStore, I’ve overseen. I basically use the implementation here:
https://github.com/jesblit/ASPNET5-FormAuthenticationLDAP

Original Post:

I have a problem with persistent logins. No matter how I configure the cookie, after 30 minutes, the User is automatically logged out (no matter how much the user interacts with the App).

I setup my App with:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCaching();
        services.AddSession(options => {
            options.IdleTimeout = TimeSpan.FromDays(1);
            options.CookieName = ".MySessionCookieName";
        });

        services.AddEntityFramework()
            .AddNpgsql()
            .AddDbContext<Model1>(options =>
                options.UseNpgsql(Configuration["Data:DefaultConnection:ConnectionString"]));

        services.AddIdentity<MinervaUser, MinervaRole>(options => {
            options.Cookies.ApplicationCookie.ExpireTimeSpan = TimeSpan.FromDays(1);
            options.Cookies.ApplicationCookie.SlidingExpiration = true;
            options.Cookies.ApplicationCookie.AutomaticAuthenticate = true;

        })
            .AddUserStore<MinervaUserStore<MinervaUser>>()
            .AddRoleStore<MinervaRoleStore<MinervaRole>>()
            .AddUserManager<MinervaUserManager>();

        services.AddMvc();
    }

And:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        if (env.IsDevelopment())
        {
            app.UseBrowserLink();
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");

            try
            {
                using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>()
                    .CreateScope())
                {

                }
            }
            catch { }
        }
        app.UseIISPlatformHandler(options => { options.AuthenticationDescriptions.Clear(); options.AutomaticAuthentication = true; });
        app.UseSession();
        app.UseIdentity();
        app.UseStaticFiles();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }

The Login Action is:

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    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, model.RememberMe, lockoutOnFailure: false);
            if (result.Succeeded)
            {

                _logger.LogInformation(1, "User logged in.");
                return RedirectToLocal(returnUrl);
            }
...

I am using the default SignInManager. As said, the Expiration Timeouts I set in Startup.Configure and Startup.ConfigureServices have no effect at all. Login -> 30mins -> automatically logged out 🙁

What to do to extend this time period?

(btw: the custom User, UserManager, UserStore don’t interfere with teh Cookie in any way, they “just” validate the credentials (what they’re supposed to 😉 ))

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

TL;DR: If you have a custom user manager, be sure to implement GetSecurityStampAsync, UpdateSecurityStampAsync and set SupportsUserSecurityStamp to true.


The solution to this is pretty simple (but I haven’t found it anywhere in the docs). As the default implementation (Create new ASP MVC6 App…) works, I checked their DB tables and found the security stamp (which I didn’t implement). According to the Answer to this question What is ASP.NET Identity’s IUserSecurityStampStore<TUser> interface? this stamp is revalidated every 30 minutes, which surprisingly fits to my problem. So, all I did was extending my own UserManager with

public class MinervaUserManager:UserManager<MinervaUser> 
// Minerva being the name of the project
{
...
    public override bool SupportsUserSecurityStamp
    {
        get
        {
            return true;
        }
    }
   public override async Task<string> GetSecurityStampAsync(MinervaUser user)
    {
        // Todo: Implement something useful here!
        return "Token";
    }

    public override async Task<IdentityResult> UpdateSecurityStampAsync(MinervaUser user)
    {
        // Todo: Implement something useful here!
        return IdentityResult.Success;
    }

These dummies always return the same SecurityStamp and “Success” on every Update. This is as secure as not having the SecurityStamps at all bit prevents the logout.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x