Refreshing stateless JWT

Currently I have an authentication feature configured like this:

Plugins.Add(new AuthFeature(() => new CustomSession(), // Subclass of AuthUserSession
  new IAuthProvider[] {
    new JwtAuthProvider(AppSettings) {
      CreatePayloadFilter = Payload.CreatePayloadFilter // Some payload func
    },
    new CustomAuthProvider(), // Subclass of CredentialsAuthProvider
  }
));

Authentication works fine. I post the following:

UserName: validUser
Password: validPass
UseTokenCookie: true

and get a response

"UserId": "6",
"SessionId": "AfrMZkrCNvs6toy3TUhB",
"UserName": "validUser",
"DisplayName": "",
"BearerToken": "ey[...]",
"ResponseStatus": {}

My question is. How am I supposed to refresh tokens so that users will not suddenly “log out” after token expiration?

Trying to post to /access-token gives a response:

"ResponseStatus": {
  "ErrorCode": "NotSupportedException",
  "Message": "JWT Refresh Tokens requires a registered IUserAuthRepository",
  "StackTrace": "[GetAccessToken: 24.05.2017 12.14.03]:[...]",
  "Errors": []
}

Adding the following line

container.Register<IUserAuthRepository>(new InMemoryAuthRepository());

makes the authentication response return a RefreshToken

"UserId": "6",
"SessionId": "AfrMZkrCNvs6toy3TUhB",
"UserName": "validUser",
"DisplayName": "",
"BearerToken": "ey[...]",
"BearerToken": "ey[...]",
"ResponseStatus": {}

Trying to post to /access-token with the refresh token gives a response:

"ResponseStatus": {
  "ErrorCode": "NotFound",
  "Message": "User does not exist",
  "StackTrace": "[GetAccessToken: 24.05.2017 13.05.57]:[...],
  "Errors": []
}

You need to use an UserAuthRepository that persists the UserAuth info into the UserAuthRepository so that when you refresh the Token, the JWT AuthProvider can source the info to create the new JWT token from the registered Auth Repository. You don’t want to use the InMemoryAuthRepository because it stores the users in memory which is lost when the AppDomain recycles.

I have another question regarding refresh tokens. What is the best option to manually invalidate already existing refresh token?

As far as I can see refresh token is not saved in IUserAuthRepository but rather that it is another JWT token and by default it is invalidated only when it is expired.

I see that JWTAuthProvider has ValidateRefreshToken method but I`m not quite sure if it is a right place to do additional check if for given userId refresh token should be invalidated.

Right, refresh tokens are stateless as well and ValidateRefreshToken is the only custom hook available to deny them if you need to, in which case you may want to look at invalidating all refresh tokens issued before a specific date (“iat”) for that user instead of trying to invalidate by its literal string.