IdentityServer 3 refresh user with refresh token IdentityServer 3 refresh user with refresh token asp.net asp.net

IdentityServer 3 refresh user with refresh token


I got it working!

As I said in the comments I used this article. The writer is referencing a very nice lib that I am using as well.

Facts:

  1. Identity Server 3 is requesting the client secret upon access token refresh
  2. One should not store the refresh_token or the client_secret on the javascript application as they are considered unsafe (see the article)

So I chose to send the refresh_token as en encrypted cookie sith this class (found of ST BTW, just can't find the link anymore, sorry...)

public static class StringEncryptor{    public static string Encrypt(string plaintextValue)    {        var plaintextBytes = plaintextValue.Select(c => (byte) c).ToArray();        var encryptedBytes = MachineKey.Protect(plaintextBytes);        return Convert.ToBase64String(encryptedBytes);    }    public static string Decrypt(string encryptedValue)    {        try        {            var encryptedBytes = Convert.FromBase64String(encryptedValue);            var decryptedBytes = MachineKey.Unprotect(encryptedBytes);            return new string(decryptedBytes.Select(b => (char)b).ToArray());        }        catch        {            return null;        }    }}

The javascript application is getting the value from the cookie. It then deletes the cookie to avoid that thing to be sent over and over again, it is pointless.

When the access_token becomes invalid, I send an http request to the application server with the encrypted refresh_token. That is an anonymous call.

The server contacts the identity server and gets a new access_token that is sent back to Javascript. The awesome library queued all other requests so when I'm back with my new token, I can tell it to continue with authService.loginConfirmed();.

The refresh is actually pretty easy as all you have to do is to use the TokenClient from IdentityServer3. Full method code:

    [HttpPost]    [AllowAnonymous]    public async Task<JsonResult> RefreshToken(string refreshToken)    {        var tokenClient = new TokenClient(IdentityServerConstants.IdentityServerUrl + "/connect/token", "my-application-id", "my-application-secret");        var response = await tokenClient.RequestRefreshTokenAsync(StringEncryptor.Decrypt(refreshToken));        return Json(new {response.AccessToken});    }

Comments are welcome, this is probably the best way to do that.


For future reference - using refresh tokens in an angular (or other JS) application is not the correct way as a refresh token is too sensitive to store in the browser. You should use silent renew based on the identityserver cookie to get a new access token. Also see the oidc-client-js javascript library, as this can manage silent renew for you.