首页 文章

Identityserver4 / OpenId Connect,混合模式,令牌刷新失败

提问于
浏览
3

我有ASP.net Core MVC站点,它使用OpenId connect与另一个ASP.net Core站点进行身份验证,该站点使用IdentityServer4,它使用另一个IdentityServer4站点作为身份提供者 .

在客户端上,只有很少的页面,理论上可以在很长一段时间内只使用AJAX调用 . 我不想刷新访问令牌的站点,这样用户就不会被迫登录,让我们说第二天 .

我已经设置了一个计时器,它调用MVC站点上的WebAPI方法,刷新令牌 .

它适用于两个第一次刷新,但总是在第三次刷新时失败 .

该方法返回一个JWT,用于外部API调用 . 我可以按预期看到第一次调用的更新,并且它获得一个新的到期时间戳 .

在第三次调用中,tokenClient.RequestRefreshTokenAsync失败,因为refreshToken为null .

public async Task<IActionResult> RefreshToken()
    {
        var disco = await DiscoveryClient.GetAsync(_authenticationOptions.Value.Authority);

        if (disco.IsError)
            return BadRequest(disco.Error);

        var tokenClient = new TokenClient(disco.TokenEndpoint, _authenticationOptions.Value.ClientId, _authenticationOptions.Value.ClientSecret);
        var refreshToken = await HttpContext.Authentication.GetTokenAsync(OpenIdConnectParameterNames.RefreshToken);
        var tokenResult = await tokenClient.RequestRefreshTokenAsync(refreshToken);

        if (tokenResult.IsError)
            return BadRequest(disco.Error);

        var old_id_token = await HttpContext.Authentication.GetTokenAsync(OpenIdConnectParameterNames.IdToken);
        var new_access_token = tokenResult.AccessToken;
        var new_refresh_token = tokenResult.RefreshToken;

        var tokens = new List<AuthenticationToken>();
        tokens.Add(new AuthenticationToken { Name = OpenIdConnectParameterNames.IdToken, Value = old_id_token });
        tokens.Add(new AuthenticationToken { Name = OpenIdConnectParameterNames.AccessToken, Value = new_access_token });
        tokens.Add(new AuthenticationToken { Name = OpenIdConnectParameterNames.RefreshToken, Value = new_refresh_token });

        var expiresAt = DateTime.UtcNow + TimeSpan.FromSeconds(tokenResult.ExpiresIn);
        tokens.Add(new AuthenticationToken { Name = "expires_at", Value = expiresAt.ToString("o", CultureInfo.InvariantCulture) });

        var info = await HttpContext.Authentication.GetAuthenticateInfoAsync("Cookies");
        info.Properties.StoreTokens(tokens);

        await HttpContext.Authentication.SignOutAsync("Cookies");
        await HttpContext.Authentication.SignInAsync("Cookies", info.Principal, info.Properties);

        return Ok(HttpContext.Authentication.GetTokenAsync("access_token").Result);
    }

我可以看到,Chrome正在控制台中通知,忽略了set-cookie标头,因为它超过了4kb .

有小费吗?

1 回答

  • 0

    得到它了 .

    客户端IdentityToken已过期,并且由于该api方法不受[Authorize]属性的保护,因此它没有更新将脚本更改为使用iframe而不是AJAX调用!

    案件结案 .

相关问题