当它存储在 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
使用 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