身份服务器4刷新令牌:如何确定过期时间?



我正在使用身份服务器 4 示例代码。 特别是,对于客户端,我将示例 MVC 客户端与混合流一起使用:https://github.com/IdentityServer/IdentityServer4/tree/master/samples/Clients/src/MvcHybrid

对于服务器,我将身份服务器与内存客户端一起使用(没有实体框架,也没有 ASP.Net 身份(:https://github.com/IdentityServer/IdentityServer4/tree/master/samples/Quickstarts

客户端和服务器都具有几乎普通的开箱即用配置。

我正在尝试了解刷新令牌如何过期,以及本机应用程序如何主动确定过期时间(在被 API 拒绝之前(。 我的理解是刷新令牌的默认过期时间很长:

http://docs.identityserver.io/en/latest/topics/refresh_tokens.html:

刷新令牌的最长生存期(以秒为单位(。默认值为 2592000 秒/30 天

但是,当示例代码请求刷新令牌时,我没有得到预期的过期时间。 下面是示例代码:

var disco = await _discoveryCache.GetAsync();
if (disco.IsError) throw new Exception(disco.Error);
var rt = await HttpContext.GetTokenAsync("refresh_token");
var tokenClient = _httpClientFactory.CreateClient();
var tokenResult = await tokenClient.RequestRefreshTokenAsync(new RefreshTokenRequest
{
Address = disco.TokenEndpoint,
ClientId = "mvc.hybrid",
ClientSecret = "secret",
RefreshToken = rt
});

tokenResult.ExpiresIn是 3600 秒,实际上是访问令牌的过期时间。 我预计是 2592000 秒。 所以问题#1是:为什么会这样?

但更重要的是,我知道刷新令牌的过期时间实际上是使用 SQL Server 作为数据存储时的默认 30 天。 有一个包含刷新令牌的表PersistedGrants,并且过期时间显然是自颁发日期起 30 天。 因此,问题 #2 是:应用如何以编程方式确定收到的刷新令牌的到期日期?

我尝试解析 RefreshToken 本身,但它并不是真正的完整 JWT,因此会引发错误:

var jwt = new JwtSecurityTokenHandler().ReadJwtToken(accessTokenResponse.RefreshToken);
var diff = jwt.ValidTo - jwt.ValidFrom;

我还搜索了 IdentityServer4 单元/集成测试,找不到内省刷新令牌的示例。

据推测,该信息要么需要位于初始令牌响应中的某个位置,要么需要在身份服务器中内置一个终结点。 但我找不到这些东西。

好的,所以答案是access_token响应中没有指示refresh_token过期时间的数据。 此外,没有可用于检查过期的终结点。

OAuth 规范对此没有任何说明,所以我不想更改access_token响应。 我最终制作了自己的端点,如果需要,它会返回到期时间。 这是我的控制器操作,如果有人需要起点:

private readonly IRefreshTokenStore _refreshTokenStore; // inject this into your controller
...
[Route("[controller]/GetRefreshTokenExpiration")]
[Authorize(...YOUR SCOPE...)]
public async Task<IActionResult> GetRefreshTokenExpiration(string refreshTokenKey)
{
var refreshToken = await this._refreshTokenStore.GetRefreshTokenAsync(refreshTokenKey);
if (refreshToken == null)
{
return NotFound(new { message = "Refresh token not found" });
}
return Ok(new {
message = "Refresh token found",
lifetime_seconds = refreshToken.Lifetime
});
}

当一个人打电话时./令 牌 我们得到access_token,expires_in,refresh_expires_in,refresh_token和其他东西

解码access_token以获取 ValidTo 从 ValidTo 中减去expires_in,然后将refresh_expires_in添加到 ValidTo,这应该会为您提供refresh_token的到期日期。

最新更新