如何触发一个用户的(完全)注销?对外从a 不同用户 会话?
例如--"管理员 "登录并签出用户 "JohnDoe"(从IdentityServer和所有客户端)。
IdentityServer支持在用户注销时通知客户端(通过前台或后台通道)。这很好,但是如何从用户会话之外开始呢?
令牌的问题是,你不能删除令牌,你必须通过从存储中删除令牌来撤销它,这样它就不能再被使用了。其实,用后道注销,你也有同样的问题。你不能直接删除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);
})