簡體   English   中英

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

[英]Identityserver4/OpenId Connect, Hybrid mode, Token Refresh Fails

我有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。

有小費嗎?

得到它了。

客戶端IdentityToken已過期,並且由於該api方法未受[Authorize]屬性保護,因此它沒有更新+更改腳本以使用iframe而不是AJAX調用!

案件結案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM