Auth cookie is deleted by the browser when it closes

perfect code 271 Reputation points
2023-01-31T19:34:06.25+00:00

I have a strange problem. When I close my browser (whether Chrome or MS Edge), my authentication cookie is deleted. Consequently, the next time I start the browser, I have to log in again.

My controller looks like this:

ClaimsIdentity claimsIdentity = new ClaimsIdentity(new List<Claim>
{
  new Claim(ClaimTypes.Name, email),
  new Claim(ClaimTypes.NameIdentifier, email),
  new Claim(ClaimTypes.Email, email)
}, "auth");
ClaimsPrincipal claims = new ClaimsPrincipal(claimsIdentity);
await HttpContext.SignInAsync(claims);
return Redirect("/");

Logout is also done via controller:

await HttpContext.SignOutAsync();
return Redirect("/");

But the logout is not executed (I checked in debug mode).

I assume I'm doing something wrong, but I don't see the error!? Does anyone have an idea what it could be?

Thank you

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,401 questions
Blazor
Blazor
A free and open-source web framework that enables developers to create web apps using C# and HTML being developed by Microsoft.
1,500 questions
ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,417 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,650 questions
0 comments No comments
{count} votes

Accepted answer
  1. Michael Taylor 51,346 Reputation points
    2023-01-31T19:43:41.84+00:00

    That's exactly how it is supposed to work. Login should only persist for the session (the tab window). This is the best practice for security and should be the default for every site you visit. Every time the user returns to your site they should have to log in.

    Imagine if you don't do this. A malicious user gains access to the user's machine, opens their browser and goes to the URL of your site. They are logged in so they can do whatever the user could do. Making login a one-time feature mostly defeats the purpose of having a login. Note that on a public computer (such as in a library) if the user went to your site and logged in then closing the browser would be how they "log out". If you didn't log them out then anyone else using that machine would be logged into their account.

    There ae sites that might offer to cache your credentials but this should only be done for sites where sensitive data isn't stored. For example you would never do this on a financial site. Some sites, including some MS sites, might even allow you to use your cached MS credentials but they require a "login" when you attempt to change sensitive data. This is overkill for many sites but useful if you really, really don't want a user to log in again. But in each case the site generally offers to remember the credentials so the user has a choice.

    As for how to enable the user to persist their login across sessions then you need to adjust your call to SignInAsync to pass a third parameter of AuthenticationProperties. Set the IsPersistent property to true. You should also strongly consider setting the ExpiresUtc as well so it doesn't persist forever though.

    In terms of your logout functionality, you should never assume it is called. Logout would only occur if the user explicitly logged out and should be used to clean up resources. However if the user closes the browser then it won't trigger a logout. Honestly there is no reliable way of knowing when a user has stopped their browsing session. There are client side things you can do but ultimately a power outage, forced close of the browser and other scenarios will override all this.


1 additional answer

Sort by: Most helpful
  1. AgaveJoe 27,696 Reputation points
    2023-01-31T20:24:19.61+00:00

    Use the SignInAsync() overload that take AuthenticationProperties and set IsPersistent = true to persist the cookie when the user closes the browser.

    var authProperties = new AuthenticationProperties
    {
        ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(20),
        IsPersistent = true
    };
            
    await HttpContext.SignInAsync(claims, authProperties);
    

    The official documentation covers the details.

    Use cookie authentication without ASP.NET Core Identity

    1 person found this answer helpful.