【问题标题】:Hook into IdentityServer4 session cookie sliding expiration挂钩 IdentityServer4 会话 cookie 滑动到期
【发布时间】:2020-12-25 19:13:04
【问题描述】:
在 IdentityServer 对会话 cookie (idsrv) 执行过期时间滑动的那一刻,我需要运行一些自定义代码(管理另一个自定义 cookie)。
我如何或在哪里可以连接到 IdentityServer 管道来完成此操作?
有什么我可以覆盖或有一个事件我可以订阅吗?
我目前在 asp.net core 3.1 应用程序中使用 IdentityServer4 3.x。
【问题讨论】:
标签:
asp.net-core
identityserver4
session-cookies
slidingexpiration
【解决方案1】:
这是使用标准 cookie 处理程序。
每当刷新 cookie 时,它不会发出任何外部事件,但是有一些方法可以通过副作用检测到这一点。
如果您使用的是自定义 ITicketStore,则可以使用 StoreAsync 检测票证何时更改。
如果您没有使用自定义票证商店,您可以在附加身份验证中间件之前附加一个中间件:
public class CookieSlidingMiddleware
{
private readonly RequestDelegate next;
public CookieSlidingMiddleware(RequestDelegate next)
{
this.next = next;
}
public async Task Invoke(HttpContext httpContext)
{
httpContext.Response.OnStarting(ResponseStarting, httpContext);
await next(httpContext);
}
public async Task ResponseStarting(object contextObject)
{
HttpContext httpContext = (HttpContext)contextObject;
var reponseCookies = httpContext.Response.Cookies;
if (httpContext.Response.Headers.ContainsKey("Set-Cookie"))
{
foreach (var setCookie in httpContext.Response.Headers["Set-Cookie"])
{
var cookie = SetCookieHeaderValue.Parse(setCookie);
if (cookie.Name == "idsrv")
{
if (cookie.Expires == null)
{
// The cookie is a session cookie, and not sliding
return;
}
else if (cookie.Expires == DateTime.UnixEpoch)
{
// the cookie is being deleted
return;
}
else if (!httpContext.Request.Cookies.ContainsKey("idsrv"))
{
// The cookie is being set for the first time
return;
}
else
{
// the cookie is being refreshed
// Do stuff here;
return;
}
}
}
}
}
}
cookie 身份验证在它自己的 Response.OnStarting 事件处理程序中处理 cookie 刷新。
此事件处理程序当前实现为函数堆栈,因此以相反的顺序调用(即此中间件必须在身份验证中间件之前调用)。
但是,我认为这个调用顺序没有任何保证,所以将来可能需要切换顺序。
【解决方案2】:
AddIdentityServer 扩展只是添加默认的 cookie 处理程序。并根据传递的值设置CookieAuthenticationOptions 属性。
根据官方描述,滑动过期是这样的:
SlidingExpiration 设置为 true 以指示处理程序在处理超过过期窗口一半的请求时重新发出具有新过期时间的新 cookie。
考虑到这些,如果您需要在 the sliding of the expiration time on the session cookie 上做某事,您需要有一个自定义的 cookie 处理程序,它会以不同的方式做事