Identity Server和ASP.NET Core Identity的Cookie分别到期

时间:2018-10-29 16:23:31

标签: asp.net-core-mvc asp.net-identity identityserver4

我目前有一个正在运行的Identity Server 4实例,该实例用于保护本机移动应用程序(iOS和Android)访问的API。对于这些移动应用程序,我们要求注销过程中要删除从Identity Server接收到的令牌(例如,不往返于Identity Server)。

我们目前在上述情况下面临的问题是,当用户注销并立即尝试再次登录时,由于存在来自以下位置的Identity Server Auth cookie,浏览器“认为”该用户已通过身份验证第一次登录。

目前,我们的Identity Server配置使用Asp.Net Core身份标识和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现在在一秒钟后过期,因此当用户退出本机应用程序并立即尝试再次登录时,将向他们显示Identity Server登录UI,并且登录按预期进行。

但是,上述更改显然会在浏览器中使用时(而不是作为登录的一部分)对Quickstart UI本身的使用产生影响,因为当Cookie一秒钟后过期时,用户会立即从快速登录中注销启动应用程序。

我希望在这里实现的可能是将ASP.Net Core Identity cookie与Identity Server使用的Auth Cookie分开-基本上是为了使Native App可以继续按原样运行(使用Identity Server Auth cookie,是无效的,因此登录后立即无效,因为这时我们有了令牌),但用户可以在浏览器中使用快速入门用户界面,而该应用的Cookie不会立即过期。

更新2018年10月30日-提议的解决方案

回顾了我的原始帖子后,总结此要求的最简单方法是,通过本地应用程序登录时,即使浏览器具有有效的身份验证Cookie,我也要求用户始终必须经过登录过程用于身份服务器。这意味着退出过程可以简单地删除本地存储的令牌,因为当用户尝试再次登录时,他们将再次经历登录过程。

我现在有一个似乎可以满足我的要求的解决方案,其中涉及为ASP.NET Core Identity和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,也总是希望用户在从本机应用程序登录时经历登录流程?

0 个答案:

没有答案