(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?