当它存储在 cookie 的声明中时,如何刷新过期的访问令牌?

How can I refresh an expired access token when it’s stored in a claim in a cookie?

使用 Identity Server 4 服务器。

在客户的Startup.Auth.cs中:

private static void ConfigureAuth(IAppBuilder app)
    {
        ISettingsReader settingsReader = Services.Resolve<ISettingsReader>();

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            ExpireTimeSpan = new TimeSpan(1, 0, 0),
            CookieSecure = CookieSecureOption.Always,
            CookieHttpOnly = true,
            SlidingExpiration = true
        });

        var platformUri = settingsReader.GetSetting("PlatformUri")?.TrimEnd('/');
        var platformApiKey = settingsReader.GetSetting("PlatformApiKey");
        var deploymentURL = settingsReader.GetSetting("deploymentURL")?.TrimEnd('/');

        var authority = $"{platformUri}/identity";

        string clientSecret;
        string clientId = SplitApiKey(platformApiKey, out clientSecret);

        var options = new OpenIdConnectAuthenticationOptions
        {
            ClientId = clientId,
            ClientSecret = clientSecret,
            Authority = authority,
            RedirectUri = $"{deploymentURL}/signin/callback",
            ResponseType = "id_token token",
            Scope = "platform openid",
            UseTokenLifetime = false,
            SignInAsAuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            Notifications = new OpenIdConnectAuthenticationNotifications
            {
                SecurityTokenValidated = SecurityTokenValidatedHandler,
                RedirectToIdentityProvider = RedirectToIdentityProviderHandler,
            }
        };

        app.UseOpenIdConnectAuthentication(options);

        AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
    }

注意 – cookie 的过期时间已设置为 5 分钟以进行调试,通常设置为一小时。

然后将 access_token 存储在经过验证的处理程序中(根据几篇文章),以便我们稍后可以将其用于 api 调用:

        private static async Task SecurityTokenValidatedHandler(SecurityTokenValidatedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
    {
        var jwtDetails = JsonWebToken.Parse(notification.ProtocolMessage.AccessToken);

        notification.AuthenticationTicket.Identity.AddClaims(
            jwtDetails.Claims.Where(c => DesiredAccessTokenClaims.Contains(c.Type)));

        notification.AuthenticationTicket.Identity.AddClaim(new Claim("access_token", notification.ProtocolMessage.AccessToken));
        notification.AuthenticationTicket.Identity.AddClaim(new Claim("id_token", notification.ProtocolMessage.IdToken));
    }

这很好用。然而,尽管 cookie 会自动刷新自己,并且会滑动过期(通常在 2-3 分钟后,而不是完整的 5 分钟后),但似乎没有办法刷新声明中持有的访问令牌,所以尽管用户将保持登录状态,但访问令牌在过期后将失效。

这是解决这个问题的正确方法吗?如果是这样,有没有办法在不打扰用户的情况下在后台更新声明中的访问令牌?似乎理想的解决方案是让 cookie 刷新也触发 SecurityTokenValidatedHandler,以便可以将更新的声明添加到新的 cookie 中,尽管尽管查看了 CookieManager 等,但似乎没有触发事件当 cookie 滑动刷新自身时。有谁知道这样做的方法吗?

非常感谢您的宝贵时间!

如果有人遇到这个问题,答案是从隐式更改为混合。 Hybrid 允许刷新令牌,而隐式的则不多。在我们的例子中,我们需要 Hybrid 和 Client Creds