Identityserver4 / OpenId Connect, Hybrid Mode, Token Updates

I have an Core MVC site that uses OpenId to authenticate with another Core site that uses IdentityServer4 that uses another site IdentityServer4 as an identity provider.

There are very few pages on the client that can theoretically be used for a long time with only AJAX calls. I do not want to update the access token so that the user is not forced to log in, say the next day.

I have set up a timer that calls a WebAPI method on the MVC site that updates the token.

It works on the first two updates, but always fails on the third.

The method returns a JWT that will be used in external API calls. I see these updates in the fist call as expected and that it is getting a new expiration label.

In the third call tokenClient.RequestRefreshTokenAsync fails because refreshToken is 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");

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

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


I see that Chrome is notifying in the console that the set-cookie header is being ignored because it is over 4kb.

Any advice?


source to share

1 answer

Got it.

The clients' IdentityToken expired and since this api method was not protected with the [Authorize] attribute, it didn't update + didn't change the script to use iframe instead of AJAX calls!

Case is closed.



All Articles