如何在ASP.NET Core中使用cookie身份验证注销所有用户?

11
我正在使用带有CookieAuthentication的ASP.NET Core MVC。有没有办法一次性注销所有用户?我尝试重置IIS - 没有起作用。我尝试删除所有用户的会话(我正在使用数据库进行会话存储) - 没有起作用。

有什么想法吗?


1
为了注销所有用户,可以更改加密密钥或重命名身份验证 cookie。 - Zygimantas
@Zygimantas,请查看此答案。https://dev59.com/_VsW5IYBdhLWcg3wO1KN#36050939 - Nkosi
@Nkosi:你的链接中使用了身份验证服务器。但问题并没有提到它,只是简单的 cookie 认证。 - Zygimantas
3个回答

4
您可以使用CookieAuthenticationOptions.SessionStore属性,在服务器端存储身份信息,以便在需要时全部清除它们。
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);
    }
}

3
使用CookieAuthentication,cookie只是包含用户姓名、角色和辅助数据的加密字符串。简而言之,它标识的是“用户”,而不是“会话”。销毁会话并不会使cookie失效。
话虽如此,您可以在cookie的辅助数据中填充会话标识符或其他令牌,然后在身份验证过程中进行验证。有人尝试这样做的示例可以在这里找到。
另一个选择是,不要使会话无效,而是在用户存储库中暂时禁用用户。使用ASPNET Identity 2.0的示例可以在这里找到。
第三个(核心)选项是更改所有Web服务器上的机器密钥,这将使任何旧的表单身份验证cookie变得无法读取,强制所有用户重新登录。

-2

这很简单。 更改登录 cookie 的名称

在 startup.cs 中,将默认名称更改为任何内容。

 options.Cookie.Name = "NewName";

完整示例:

  services.ConfigureApplicationCookie(options =>
            {
                options.Cookie.Name = "NewName"; //<-- Here
                options.Cookie.HttpOnly = true;
              ...
                options.Events = options.Events ?? new CookieAuthenticationEvents();
                var onForbidden = options.Events.OnRedirectToAccessDenied;
                var onUnauthorized = options.Events.OnRedirectToLogin;
                options.Events.OnRedirectToAccessDenied = (context) => OnRedirect(context, onForbidden, HttpStatusCode.Forbidden);
                options.Events.OnRedirectToLogin = (context) => OnRedirect(context, onUnauthorized, HttpStatusCode.Unauthorized);
            });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接