IdentityServer4 refresh token invalid grant

Viewed 10278

I'm having some issues on requesting new refresh tokens in IdentityServer4. Sometime after authentication, I get an Unauthorized response from my API, ok, but when I try to request a new refresh token, I get an invalid_grant from the server. I made sure that I set offline_access, but am still encountering the problem. Here is my code:

My Client in Server Config.cs

new Client
            {
                ClientId = "myclientId",
                ClientName = "MyClient",
                AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,

                RequireConsent = false,

                ClientSecrets =
                {
                    new Secret("mySecret".Sha256())
                },

                RedirectUris = { "http://localhost:5002/signin-oidc" },
                PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },

                AllowOfflineAccess = true,

                UpdateAccessTokenClaimsOnRefresh = true,

                AllowedScopes =
                {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
                    IdentityServerConstants.StandardScopes.OfflineAccess,
                    ...
                }
            }

My Startup.cs from MVCclient

app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationScheme = "Cookies",
            AccessDeniedPath = "/Home/Error403"
        });

        app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
        {
            AuthenticationScheme = "oidc",
            SignInScheme = "Cookies",

            Authority = Configuration["Identity.Url"],
            RequireHttpsMetadata = false,

            ClientId = Configuration["ClientId"],
            ClientSecret = Configuration["ClientSecret"],

            ResponseType = "code id_token",

            Scope = { "openid profile offline_access" },

            GetClaimsFromUserInfoEndpoint = true,
            SaveTokens = true,

        });

Here I'm getting invalid_grant

var disco = await DiscoveryClient.GetAsync(Configuration["Identity.Url"]);
        if (disco.IsError) throw new Exception(disco.Error);

        var tokenClient = new TokenClient(disco.TokenEndpoint, Configuration["ClientId"],
            Configuration["ClientSecret"]);
        var rt = await HttpContext.Authentication.GetTokenAsync("refresh_token");
        var tokenResult = await tokenClient.RequestRefreshTokenAsync(rt);

tokenResult is assigned invalid_grant. Am I missing something?

4 Answers

I found that this happens when IdentityServer is put to sleep by IIS. We had a dev server which did not have a "Keep alive / awake" policy, so if left for some time (20 minutes I think) the site is put to sleep... When used again, this screwed up any attempt at using refresh tokens, but strangely instead of claiming I had an invalid refresh token, got an error of "Invalid Grand Type" in the response.

I've just faced with the same error. I noticed that the error occured when I try to refrsh access token within short period of time, ex. twice per second. Solution was to increase RefreshTokenUssage parameter in database (table dbo.Clients) for client up to 10 (original value is 1).

I fixed this issue by editing these lines

 AllowedGrantTypes = { "authorization_code", "refresh_token" },
 RefreshTokenUsage = TokenUsage.OneTimeOnly,
 RefreshTokenExpiration = TokenExpiration.Sliding,
 SlidingRefreshTokenLifetime = 2592000 * 2

Your identity server also allows the client to refresh the token. Refresh token will expire after 60 days. Every time refreshing the access token also updates the refresh token to a new value.

You must log out and log in to get the new refresh token, then you can use your new refresh token to refresh the access token later.

Reference: https://identityserver4.readthedocs.io/en/latest/topics/refresh_tokens.html#additional-client-settings

Related