asp.net-core-mvc - Identity Server 和 ASP.NET Core Identity 的单独 Cookie 过期时间
问题描述
我目前有一个有效的 Identity Server 4 实例,用于保护本机移动应用程序(iOS 和 Android)访问的 API。对于这些移动应用程序,我们要求退出过程是删除从 Identity Server 接收到的令牌的情况(例如,没有到 Identity Server 的往返)。
我们目前面临的问题是,当用户退出并立即尝试再次登录时,浏览器“认为”用户已经通过身份验证,因为第一次登录时存在 Identity Server Auth cookie在。
目前我们的 Identity Server 配置使用 Asp.Net Core Identity 和Quickstart UI,我已经能够通过将 ASP.NET Core Identity cookie 的过期时间更改为 1 秒来解决这种情况,如下所示:
services.AddIdentity<UserEntity, ApplicationRoleEntity>()
.AddEntityFrameworkStores<UserContext>()
.AddDefaultTokenProviders();
services.ConfigureApplicationCookie(options =>
{
options.ExpireTimeSpan = TimeSpan.FromSeconds(1);
});
因为 Auth cookie 现在在一秒钟后过期,所以当用户退出 Native 应用程序并立即尝试再次登录时,他们会看到 Identity Server 登录 UI,并且登录会按预期工作。
然而,当在浏览器中使用时(不是作为登录的一部分),上述更改显然会影响 Quickstart UI 本身的使用,因为当 cookie 在一秒钟后过期时,用户会立即从快速启动应用程序中注销。
我希望在这里实现的可能是将 ASP.Net Core Identity cookie 与 Identity Server 使用的 Auth Cookie 分开 - 基本上这样 Native App 可以继续按原样运行(使用立即无效的 Identity Server Auth cookie登录后无效,因为此时我们有我们的令牌)但用户可以在浏览器中使用快速启动 UI,而他们的该应用程序的 cookie 不会立即过期。
2018 年 10 月 30 日更新 - 建议的解决方案
查看我的原始帖子后,总结此要求的最简单方法是,当通过本机应用程序登录时,我要求用户始终必须通过登录过程,即使浏览器具有有效的身份验证 cookie服务器。这意味着注销过程可以简单地删除本地存储的令牌,因为当用户尝试再次登录时,他们将再次经历登录过程。
我现在有一个似乎可以满足我的要求的解决方案,它涉及为 ASP.NET Core Identity and Identity Server 使用的应用程序 cookie 创建一个 CookieEvents 类。这是在启动时设置如下。
services.ConfigureApplicationCookie(options =>
{
options.EventsType = typeof(CookieEvents);
});
在 CookieEvents 类中,当授权端点发生登录事件时,我将一个新项目添加到 AuthenticationItems.Items 字典中。在未来从本机移动应用程序(我使用 CookieEvents 的 ValidatePrincipal 中的查询字符串中的 client_id 识别)向授权端点发出登录请求时,我然后检查是否存在添加到 cookie 的项目,如果找到,则主体是被拒绝,这会强制用户再次执行登录过程,即使用于登录的浏览器具有有效的身份验证 cookie。下面的 CookieEvents 类示例(为简洁起见,删除了私有方法)
public override Task SigningIn(CookieSigningInContext context)
{
if (IsRequestToAuthorizeEndpoint(context.Request) &&
!context.Properties.Items.ContainsKey("signed-in"))
{
context.Properties.Items.Add("signed-in", "true");
}
return base.SigningIn(context);
}
public override Task ValidatePrincipal(CookieValidatePrincipalContext
context)
{
if (IsNativeAppSignIn(context.Request) &&
context.Properties.Items.ContainsKey("signed-in"))
{
context.RejectPrincipal();
return Task.CompletedTask;
}
return base.ValidatePrincipal(context);
}
在测试中,这似乎运行良好,也意味着如果用户在浏览器中使用实际 UI,他们现在不再立即退出,因为 1 秒到期不再存在。
作为一种解决方案,这种方法是否存在任何明显的缺陷,即始终希望用户在从本机应用程序登录时通过登录流程,即使他们的浏览器具有身份验证 cookie?
解决方案
推荐阅读
- javascript - 如何使用 facebook sdk 共享用户位置?(脸书签到)
- java - 如何使用 REST 模板 Spring MVC 获取大型 JSON 而不会在 java 中出现内存问题
- .net - 配置文件 sku 是否指定了所需的单个确切或最低 .NET Framework?
- r - 网站扩展删除非“.htm”链接
- c++ - asio::io_context::run_one() 和 while()
- javascript - VanillaJS 到 VueJS 错误:Flickity 的坏元素:轮播
- r - 在一个数据框中连接多个数据框列表
- javascript - 如何安全地从任意 html 中提取文本内容
- java - java.util.Vector 中元素计数和元素数据的值不同
- r - 迭代地组合两个字符向量