如何通过不同用户的会话为用户外部触发(完全)注销?
例如,“管理员”登录并注销用户“ JohnDoe”(来自IdentityServer和所有客户端)。
IdentityServer支持在用户注销时(通过前通道或后通道)通知客户端。太好了,但是如何从用户会话之外开始滚动呢?
答案 0 :(得分:1)
令牌的问题是您无法删除令牌,必须通过从商店中将其删除来撤消令牌,以使其不再可用。实际上,使用反向通道注销会遇到相同的问题。您无法直接删除Cookie,但客户端可以在下一个请求时拒绝它。
对于用户会话,反向通道注销可以从IdentityServer网站上可用的cookie中读取会话信息。但是,管理员无权访问此信息,因此您需要存储用户会话服务器端。
这可以在客户端或IdentityServer上。我将在客户端实现一个会话管理器,因为是客户端验证cookie并可以删除cookie(在下一个请求时)。
这允许IdentityServer执行正常的反向通道注销,并将其留给客户端以从LogoutCallback
上的会话管理器中删除一个或所有条目。这样,您可以为不同的客户实施不同的策略。
如果会话不可用,客户端可以向会话管理器咨询cookie验证并拒绝访问。像这样:
public class CookieEventHandler : CookieAuthenticationEvents
{
private SessionManager _sessionManager { get; }
public CookieEventHandler(SessionManager sessionManager)
{
_sessionManager = sessionManager;
}
public override async Task ValidatePrincipal(CookieValidatePrincipalContext context)
{
if (context.Principal.Identity.IsAuthenticated)
{
var sub = context.Principal.FindFirst("sub")?.Value;
if (!_sessionManager.HasSession(sub))
{
context.RejectPrincipal();
await context.HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
}
}
}
}
在启动时:
services
.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies", options =>
{
options.EventsType = typeof(CookieEventHandler);
})