Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to logout all users in ASP.NET Core cookie authentication?

I'm using ASP.NET Core MVC with CookieAuthentication. Is there a way I can sign all users out at once? I tried resetting IIS - didn't work. I tried deleting all the users' sessions (I'm using a database for session storage) - didn't work.

Any ideas?

like image 953
John-Luke Laue Avatar asked May 17 '17 00:05

John-Luke Laue


2 Answers

You can use CookieAuthenticationOptions.SessionStore Property, to store identity information in server side so you can clear it all when you need.

public void ConfigureServices(IServiceCollection services)
{
    MemoryCacheTicketStore memoryCacheTicketStore = new MemoryCacheTicketStore();
    services.AddSingleton<MemoryCacheTicketStore>(memoryCacheTicketStore);

    services.AddAuthentication().AddCookie(cfg =>
    {
        cfg.SessionStore = memoryCacheTicketStore;
    });
}

public class SessionController : Controller
{
    private readonly MemoryCacheTicketStore memoryCacheTicketStore;

    public SessionController(MemoryCacheTicketStore memoryCacheTicketStore)
    {
        this.memoryCacheTicketStore = memoryCacheTicketStore;
    }

    public Task ClearAllSession()
    {
        return memoryCacheTicketStore.ClearAll();
    }
}

public class MemoryCacheTicketStore : ITicketStore
{
    private const string KeyPrefix = "AuthSessionStore-";
    private IMemoryCache _cache;

    public MemoryCacheTicketStore()
    {
        _cache = new MemoryCache(new MemoryCacheOptions());
    }

    public async Task ClearAll()
    {
        _cache.Dispose();
        _cache = new MemoryCache(new MemoryCacheOptions());
    }

    public async Task<string> StoreAsync(AuthenticationTicket ticket)
    {
        var guid = Guid.NewGuid();
        var key = KeyPrefix + guid.ToString();
        await RenewAsync(key, ticket);
        return key;
    }

    public Task RenewAsync(string key, AuthenticationTicket ticket)
    {
        var options = new MemoryCacheEntryOptions();
        var expiresUtc = ticket.Properties.ExpiresUtc;
        if (expiresUtc.HasValue)
        {
            options.SetAbsoluteExpiration(expiresUtc.Value);
        }
        options.SetSlidingExpiration(TimeSpan.FromHours(1)); // TODO: configurable.

        _cache.Set(key, ticket, options);

        return Task.FromResult(0);
    }

    public Task<AuthenticationTicket> RetrieveAsync(string key)
    {
        AuthenticationTicket ticket;
        _cache.TryGetValue(key, out ticket);
        return Task.FromResult(ticket);
    }

    public Task RemoveAsync(string key)
    {
        _cache.Remove(key);
        return Task.FromResult(0);
    }
}
like image 102
Kahbazi Avatar answered Sep 22 '22 19:09

Kahbazi


With CookieAuthentication, the cookie is simply an encrypted string containing the user's name, roles, and auxilliary data. In short, it identifies the user, not the session. Killing sessions does not invalidate the cookie.

That being said, you can stuff a session identifier or other token in the cookie's auxiliary data, and then validate that during the authentication process. An example of someone trying to this can be found here.

Another option is instead of invalidating sessions you can temporarily disable users in your user repository. Here is an example using ASPNET Identity 2.0.

A third (nuclear) option is to change the machine key on all web servers, which will render any old forms authentication cookies unreadable, forcing all users to sign on again.

like image 34
John Wu Avatar answered Sep 22 '22 19:09

John Wu