我卡住了,需要一些建议或指向解决方案的指针。我有一个相当简单的IdentityServer4设置,用于我们的单点登录实现。
三个应用
具有 asp.net 核心身份的身份服务器4(ID 服务器)
ASP.NET 核心 2.2 MVC (客户端 1)
ASP.NET 核心 2.2 MVC (客户端 2) MVC 客户端是使用混合授权设置的
两种情况:
- 如果用户在任何一个客户端(例如客户端 1)中处于活动状态,则在该应用程序(客户端 2) 中达到空闲超时后,用户不应在客户端 2 中注销。 如果用户在两个客户端(客户端 1 和客户端 2)
- 中都处于非活动状态,则当空闲超时超过时,系统应从所有客户端(客户端 1 和客户端 2)注销用户。
方案 1:用户在任何一个客户端中处于活动状态。 用户在客户端 1 中处于活动状态,在客户端 2 中处于空闲状态 预期行为: 当空闲超时超过时,系统不应从客户端 2 注销。 当前身份行为: 能够在客户端 1 中继续工作,但客户端 2 和 ID 服务器在超过空闲时间后导航到登录页面。
场景 2: 用户在所有 2 个客户端(客户端 1 和客户端 2)中处于非活动状态 预期行为: 当空闲超时超过时,系统应从所有 2 个客户端和 ID 服务器注销用户。
如果我仅在 ID 服务器中设置 cookie 过期时间(删除的滑动过期时间为真,并且客户端 1 和客户端 2 中的 cookie 过期时间),则即使两个客户端都处于空闲状态,客户端应用程序也会连续工作,直到 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);
})
身份服务器:
services.AddIdentityServer(options =>
{
options.Authentication.CookieLifetime = TimeSpan.FromMinutes(15);
options.Authentication.CookieSlidingExpiration = true;
})
首先需要回答的问题是:什么系统,在哪里?
浏览器客户端不受信任,不应干扰。我认为最好恢复cookie设置。不要让前面尝试触发注销。
最好跟踪后端的用户。您可以通过在 Mvc 客户端中添加一个服务来实现此目的 1.通过身份服务器 2 将用户注册为活动用户。跟踪活动和 3.当用户看起来处于非活动状态的时间过长时,由 IdentityServer 取消注册用户。查看 IdentityServer 附带的令牌清理服务,了解如何使用间隔更新列表的一些灵感。
在启动两个 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。这意味着您可以在此处更新用户活动时间戳(用于跟踪用户),这意味着您不必一直联系 IdentityServer。仅当状态发生更改时,服务才应联系身份服务器:用户已变为活动或非活动状态。
现在,您需要向IdentityServer添加服务,以便在一个中心位置跟踪用户。您可以在存储中保留用户的状态。在用户变为活动状态时添加用户(每个客户端),并在用户不再处于活动状态时将其删除。从此列表中删除用户的最后一个会话时,触发反向通道注销。
反向通道注销可以向 mvc 客户端发出用户已注销的信号。使用 CookieEventHandler,用户将被拒绝访问。这不会在注销时更新前面,但在用户联系 mvc 客户端时有效。它将发现自己已注销所有应用程序和身份服务器。
当您点击链接时,您将看到 CookieEventHandler 的实现。并在互联网上搜索反向通道注销,您可能会找到可以使用的示例。
我们采取的方法,我认为符合 OIDC 规范精神的方法就是 IDP 会话是主会话,可以长期存在。IDP 不关心客户端会话,但客户端应监视 IDP 会话(会话监视规范),当 IDP 注销时,客户端会话也应注销(前端或后端通道)。从客户端显式注销也应将您从 IDP 会话中注销。
此外,由于该协议支持prompt=login
和max_age=n
因此,即使 IDP 上已存在活动会话,您也可以强制执行交互式身份验证。这允许客户端对用户必须进行身份验证的频率实施自己的策略 - 例如,要访问管理功能,您必须在过去 5 分钟内进行身份验证或类似的东西。
同样整洁的是,如果在 IDP 身份验证 cookie 过期时启动会话监控,但开箱即用,IDS4 不会发生这种情况。但是,应该可以创建自定义 IUserSession 实现,使会话 ID cookie 与主身份验证 cookie 正确对齐。