title: Identityserver4/OpenId Connect, Hybrid mode, Token Refresh Fails
body: <p>I have as ASP.net Core MVC site, that uses OpenId connect to authenticate with another ASP.net Core site, that uses IdentityServer4, that uses another IdentityServer4 site as identity provider.</p>
  
  <p>On the client, there is a very few pages, that in theory could be used for a long time with only AJAX-calls. I wan't the site to refresh the access token, so that the user won't be forced to log in, let's say the next day.</p>
  
  <p>I've set up a timer, that calls a WebAPI method on the MVC-site, that refreshes the token.</p>
  
  <p>It works with the two first refreshes, but always fails on the third.</p>
  
  <p>The method returns a JWT to be used on external API-calls. I can see this updates on the fist call as expected, and that it gets a new expiration timestamp.</p>
  
  <p>In the third call, the tokenClient.RequestRefreshTokenAsync fails, because the refreshToken is null.</p>
  
  <pre><code>    public async Task&lt;IActionResult&gt; 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&lt;AuthenticationToken&gt;();
          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);
      }
  </code></pre>
  
  <p>I can see, that Chrome is notifying in the console, that a set-cookie header is ignored, because it exceeds 4kb.</p>
  
  <p>Any tips?</p>