如何跨客户端应用程序和 Identityserver4 处理空闲会话超时

How to handle idle session timeout across client apps and Identityserver4

我卡住了,需要一些建议或指向解决方案的指示。我有一个相当简单的 IdentityServer4 设置来实现我们的单点登录。

三个应用程序

具有 asp.net 核心身份(ID 服务器)的 IdentityServer4

ASP.NET Core 2.2 MVC (client1)

ASP.NET 核心 2.2 MVC(客户端 2) MVC 客户端是使用 Hybrid Grant

设置的

两种情况:

  1. 如果用户在任何一个客户端(例如客户端 1)中处于活动状态,则在该应用程序(客户端 2)达到空闲超时后,用户不应在客户端 2 中注销。
  2. 如果用户在两个客户端(client1 和 client2)中都处于非活动状态,那么当空闲超时超过时,系统应该从所有客户端(client1 和 client2)中注销用户。

场景一:用户活跃于任一客户端。 用户在 client1 处于活动状态,在 client2 处于空闲状态 预期行为: 当空闲超时超过时,系统不应从 client2 注销。 当前身份行为: client1 可以继续工作,但是 client2 和 ID server 在空闲时间超过后导航到登录页面。

场景二: 用户在所有 2 个客户端(client1 和 client2)中都处于非活动状态 预期行为: 当空闲超时超过时,系统应从所有 2 个客户端和 ID 服务器注销用户。

如果我仅在 ID 服务器中设置 cookie 过期时间(删除了 slidingexpiration 为真且 cookie 在 client1 和 client2 中过期时间),那么即使两个客户端在 ID 服务器之前都处于空闲状态,客户端应用程序仍会连续工作而没有过期时间过期时间已过,客户端应用程序正在连续工作。

我想知道是否可以实现预期的行为

客户:

 .AddCookie(options =>
                {
                    // Configure the client application to use sliding sessions
                    options.SlidingExpiration = true;
                    // Expire the session of 15 minutes of inactivity
                    options.ExpireTimeSpan = TimeSpan.FromMinutes(15);
                })

ID 服务器:

services.AddIdentityServer(options =>
            {
                options.Authentication.CookieLifetime = TimeSpan.FromMinutes(15);
                options.Authentication.CookieSlidingExpiration = true;
            })

首先需要回答的问题是:什么系统,在哪里?

浏览器客户端不可信,不应干涉。我认为最好恢复 cookie 设置。不要让前端尝试触发注销。

最好在后台跟踪用户。您可以通过在 Mvc 客户端中添加一项服务来实现此目的,该服务 1. 通过 IdentityServer 将用户注册为活动用户,2. 跟踪 activity 和 3. 当用户似乎长时间处于非活动状态时,通过 IdentityServer 注销用户。查看 IdentityServer 附带的 token cleanup 服务,了解如何使用间隔更新列表的一些灵感。

在两个 Mvc 客户端的启动中为 cookie 添加一个处理程序:

Services
    .AddAuthentication(options =>
    {
        options.DefaultScheme = "Cookies";
        options.DefaultChallengeScheme = "oidc";
    })
    .AddCookie("Cookies", options =>
    {
        // you'll need to create your own handler
        options.EventsType = typeof(MyCookieEventHandler);
    })

我不会在此处添加代码,而是解释其目的:每次用户需要访问安全源时都会调用 cookiehandler。这意味着您可以在此处更新用户 activity 时间戳(用于跟踪用户),这意味着您不必一直联系 IdentityServer。仅当状态发生变化时,服务才应联系 IdentityServer:用户已变为活动或非活动状态。

现在您需要向 IdentityServer 添加一项服务,以便在中央位置跟踪用户。您可以在商店中保留用户的状态。在用户变为活动状态时添加用户(每个客户端),并在用户不再活动时删除用户。当用户的最后一个会话从此列表中删除时,触发 backchannel logout.

反向通道注销可以向 mvc 客户端发出用户已注销的信号。然后使用 CookieEventHandler 拒绝用户访问。这不会在注销时更新前端,但会在用户联系 mvc 客户端时生效。它会发现自己已退出所有应用程序和 Identityserver。

当您关注 link 时,您将看到 CookieEventHandler 的实现。并在互联网上搜索 backchannel logout,您可能会找到可以使用的示例。

我们采用的方法,我认为符合 OIDC 规范精神的方法是 IDP 会话为主,可以长期存在。 IDP 不关心客户端会话,但客户端应监视 IDP 会话(会话监视规范),并且当 IDP 注销时,客户端会话也应注销(前台或后台通道)。从客户端显式注销也应该让您退出 IDP 会话。

此外,由于该协议支持 prompt=loginmax_age=n,因此即使 IDP 上已存在活动会话,您也可以强制执行交互式身份验证。这允许客户端针对用户必须多久进行一次身份验证实施自己的策略 - 例如要访问管理功能,您必须在过去 5 分钟内或类似的时间内进行身份验证。

如果会话监控在 IDP 身份验证 cookie 过期时启动,但开箱即用,这不会发生在 IDS4 中,这也很巧妙。但是,应该可以创建自定义 IUserSession 实现,将会话 ID cookie 与主身份验证 cookie 正确对齐。