(continuation of conversation of this pull request https://github.com/ServiceStack/ServiceStack/pull/1248)
We have done some more deep dive security reviews on this, and I wanted to open a discussion on how the JwtAuthProvider works as it is now, in a specific scenario, and how it works together with the GetSessionTokenService, and see what can be done.
In the specific scenario we are looking at, we use httponly cookies to maintain a browser “session” between a JSApp (React) and a WebServer (ServiceStack) where we host the AuthenticateService and the GetAccessTokenService services.
The JSApp obtains a JWT from the webserver by passing username+password to a CredentialsAuthProvider+ JwtAuthProvider. The result is a response like this, and we want the ss-reftok cookie as well.
"userId": "user_wAXnNtUtQEeZJAenWaeKNQ",
"sessionId": "gLc2Jesk2zg3fvGIfS1o",
"userName": "auser@company.com",
"displayName": "afirstname alastname",
"bearerToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6InljTCJ9.eyJpc3MiOiJzc2p3dCIsInN1YiI6InVzZXJfd0FYbk50VXRRRWVaSkFlbldhZUtOUSIsImlhdCI6MTYyODEzODcyOCwiZXhwIjoxNjMwNzMwNzI4LCJlbWFpbCI6ImF1c2VyQGNvbXBhbnkuY29tIiwiZ2l2ZW5fbmFtZSI6ImFmaXJzdG5hbWUiLCJmYW1pbHlfbmFtZSI6ImFsYXN0bmFtZSIsIm5hbWUiOiJhZmlyc3RuYW1lIGFsYXN0bmFtZSIsInJvbGVzIjpbInN0YW5kYXJkIl0sImp0aSI6MX0.SADZP96CO6m0XFwTsiBE47AvB5zqJcgSFf5g-WbEhyGj0J95uNXh4OY2ge61BZ3WShJChJuwmDDzTHqFmxuReC0qvGD5FcBihSemQuoYJ6Uz0mL_dGpH7LksCCBNEX3fOXFEkSB9EQ_o80CMrTfYFJiFmoHZils4d315HEqRm4ttiBH51QcvInWbANQ-rYiRJxbQhdoDWj5J7v4ox_BVke-n6kZpH02l1svjPuTbdomu3blWjprJvJZWLEwFVCOmJTkFbXMs0UUqzaL6Dzw0l1TvmXIykOtMxCYLWpXzdlItS8M56fBZclsi48UndUm62C2aEI2OqI_btdp5neIFhg",
"refreshToken": "eyJ0eXAiOiJKV1RSIiwiYWxnIjoiUlMyNTYiLCJraWQiOiJ5Y0wifQ.eyJzdWIiOiJ1c2VyX3dBWG5OdFV0UUVlWkpBZW5XYWVLTlEiLCJpYXQiOjE2MjgxMzg3MjgsImV4cCI6MTY1OTY3NDcyOCwianRpIjotMX0.aq9P75EuE2_IB-Veansl_0JyIo7DwxfUJFG07pwtx3HGVAhGIMJMkY2QudhFr89x6g_4NhfvZcOVT1rFQXOeS_GxGngpstTPfQnmlUzs3HGt0f7uGsCBkl7AB59m0v7Zo5m6vlfZIn2kH_PaTi8BQ1ecpDPF6Mx6eBerOGt2JIJCIDTZELVKdjq9YTDZNoy8IwsJU1r0NWnQd6lYPNo1VymDuCzZhbUTAHJSwWO9g-Pajf21qIoYB8rrO5vYeaYArEJDChJ57qxlJGAChkVthlC6hRlZzvpI3VsOT1smI1aMtXMXc2LW7wR_bfoNRfVy0TXTuubVPENg6PemHe1p1w",
At some time later, when the access_token value has expired (or close to it), we want to make a call from the JSApp to the webserver passing only the ss-reftok cookie, and receiving: a new ss-reftok cookie and receiving a new access_token from the response JSON, like this:
{
"accessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6InljTCJ9.eyJpc3MiOiJzc2p3dCIsInN1YiI6InVzZXJfd0FYbk50VXRRRWVaSkFlbldhZUtOUSIsImlhdCI6MTYyODEzODk0OCwiZXhwIjoxNjMwNzMwOTQ4LCJlbWFpbCI6ImF1c2VyQGNvbXBhbnkuY29tIiwiZ2l2ZW5fbmFtZSI6ImFmaXJzdG5hbWUiLCJmYW1pbHlfbmFtZSI6ImFsYXN0bmFtZSIsIm5hbWUiOiJhZmlyc3RuYW1lIGFsYXN0bmFtZSIsInJvbGVzIjpbInN0YW5kYXJkIl0sImp0aSI6Mn0.MZwvADjIi0x-4nNY1zOGoj3G6NvzoPKAz8bYQ1ZqjWoFIcCTDPeHcpSBGiQzO-pq4iBoQKNaedX9EWO90d_rHRJepd6Sb5YoV69z1AICaiQ8j4z3trUjE1-du9XiydqWdZiN3k-DSpTxG_6o9btatoNeBca-5xKHzDa4JTTJPRA7hUlgU3iMW6WQlmUz8YgGeb2UKyVD25UppCv5Fmy3dU9V11W9AlbTE6ioVoue_fEjmJLInhF9FCn0xl5AbOQ_yTluZDug3uNkJfMO7t-WSaYXWt7QPwECljaiJYgg2AkT89pwTVkPL5qkFBSlKzNk7t2Yoz1R0oxTOI1AzKfuug"
}
In this scheme, we need the ss-reftok cookie to maintain a login state between the browser and server for longer than the 15mins long access_token expiry - the the week long expiry of the ss-reftok.
So, given the answer in the pull request, which we accept, we would then hope to only turn ON ss-reftok with jwtAuthProvider.UseRefreshTokenCookie= true and turn OFF ss-tok with jwtAuthProvider.UseTokenCookie= false, to get our access_token in the JSON of the response to POST /access-token.
Otherwise, we have no way of getting the actual access_token value into the JSApp (for later use with an API) AND at the same time keep the cookie session connection between browser and webserver to preserve the login between browser sessions.
Would you agree with us that this should be possible securely?