繁体   English   中英

IdentityServer4 刷新令牌:如何确定过期时间?

[英]IdentityServer4 Refresh Token: How to determine expiration time?

我正在使用 Identity Server 4 示例代码。 特别是,对于客户端,我使用带有混合流的示例 MVC 客户端: https : //github.com/IdentityServer/IdentityServer4/tree/master/samples/Clients/src/MvcHybrid

对于服务器,我将 Identity Server 与内存客户端一起使用(没有实体框架,也没有 ASP.Net Identity): 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 单元/集成测试,但找不到内省刷新令牌的示例。

据推测,该信息要么需要在初始令牌响应中的某个地方,要么需要在 Identity Server 中内置一个端点。 但我找不到这些东西。

好的,所以答案是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
    });
}

当调用 ../token 时,我们会得到 access_token、expires_in、refresh_expires_in、refresh_token 等

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM