0

I have an application developed using React in the front-end and ASP.Net Web API in the backend. I am using JWT for authorization. The process is

  1. When a user logs in and is authenticated, 2 tokens are sent to the front-end, access token and refresh token. An access token is the JWT and a refreshes token is a random string and a refresh token is stored in a database.
  2. For every subsequent call to APIs access token is attached in the header, I have an authentication filter that validates the access token.
  3. Once the access token is expired, a 401 status is thrown with the error message TokenExpired.
  4. Once the front-end receives 401, it calls the refresh token API to get the refresh token

The question I have is that I cannot have an authentication filter to validate the access token of refresh tokens API as it will throw 401 due to the expired access token, so I need to make the refresh token API to be anonymous so it does not hit authentication filter. If I make anonymous I am making a call to the database to get the refresh token stored for the user and compare it with the one I received from the front-end. So is it safe to make the refresh token API anonymous, if not what's the best way?

Milad Dastan Zand
  • 1,062
  • 1
  • 10
  • 21
Raghul Raman
  • 169
  • 1
  • 5
  • 18
  • when you validate access token are you using the public key from JWKS to check the signature? if so, it was a public key, anyone can create a signature of any JWT using the public key (RSA/ECDSA from the JWKS public url. So if the access token is public it should not used for auth. If you validate a HMAC signature, then the signing of the JWT was done using a preshared secret and should be considered sensitive for auth, and by extension the refresh is equal to the access token. What kind of JWT are you using, what is it used for? – Stof Nov 24 '21 at 05:35
  • The JWT is signed using preshared secret key. Since it’s REST API in the backend and stateless, jwt is used for authorization and construct principal object. – Raghul Raman Nov 24 '21 at 05:43
  • @stof wrong, you can't sign a token with the public key. Tokens are signed with the private key and verified with the public key. And that's also not the question of the OP. – jps Nov 24 '21 at 06:04
  • Simple steps ae mentioned to another post: https://stackoverflow.com/questions/27726066/jwt-refresh-token-flow – Maksud Nov 24 '21 at 06:18
  • @Jps it is correct, go disagree with the spec. You're referring to the HMAC varient that expects a pre-shared secret that you may decide is a private key but the spec designed the RSA/ECDSA for the purposes of encryption. Ergo only 1 side can hold the private key and never share it, meaning 1 side would only be able to create a signature, the other side can't recreate that signature fkr verification if they don't have the private key.. It's nonsensical. Private keys are for deciphering, shared secrets are for signing HMAC or alternatively a public key for signing encrypted token claims – Stof Nov 24 '21 at 06:55
  • Also a comment is not an answer, so im not required to directly answer the question and free to ask whatever questions i feel are necessary for clarity. get your community ethics in check or you're going to be reported a lot – Stof Nov 24 '21 at 06:56
  • @Stof No, I'm not refering to HMAC. I'm refering to your claim *it was a public key, anyone can create a signature of any JWT using the public key (RSA/ECDSA* - it sounds for me like you want to tell us that everyone can sign a token with a public key and it is not safe. And I just said that tokens are signed with the private key and verified with the public key. – jps Nov 24 '21 at 08:37
  • incorrect, it is safe, a signature is integrity only. signatures are entirely separate from enciphering with a public key and deciphering with only the private key. HMAC is a signature, not encryption, signatures are generated on 1 side using a secret, and regenerated on the other side with the same secret for **integrity** not data protection, no keys are invoked, no data protection is involved. you seem to be confusing these very different concepts into 1 thing. JWT can use one, or the other, or both together. the question i asked is which is used. – Stof Nov 24 '21 at 08:50
  • oh well, I didn't say a word about HMAC and I didn't make any claim regarding encryption... – jps Nov 24 '21 at 09:01
  • every time you say 'signed' you refer to the JWT signature, a signature is a HMAC for JWTs, go look at jwt.io. no wonder you're confused if you don't correlate the word signature with HMAC, and now I see it might have been a better conversation if i directed you to jwt.io first – Stof Nov 25 '21 at 14:53

2 Answers2

0

At Auth0, Created a set of features that mitigate the risks associated with using refresh tokens by imposing safeguards and controls on their lifecycle. Our identity platform offers refresh token rotation, which also comes with automatic reuse detection.

Please read the following topic.

Refresh Token Rotation

Refresh Token Automatic Reuse Detection

Maksud
  • 305
  • 1
  • 13
  • We are doing kind of refresh token rotation. When a new access token is requested we validate with the refresh token and provide a new access token and a new refresh token and the refresh token is updated in database. However I don’t think we can store the list of all refresh tokens generated so far as mentioned in automatic reuse detection – Raghul Raman Nov 24 '21 at 06:55
0

The JWT is signed using preshared secret key. Since it’s REST API in the backend and stateless, jwt is used for authorization and construct principal object

As you say, the access token represent authorisation in your application, if the refresh token is exposed then the refresh token can be presented by a bad actor to obtain an access token they can use for the same authorisation.

Using a 'preshared secret' indicates the JWT is a HMAC only variant of JWT, i.e. there is no encryption as that would indicate private and public key pair opposed to a 'preshared secret'. So the JWT is essentially a signature for the puposes of security characteristics we are ensuring integrity that the claims of the JWT are well-formed and have not been changed since signed. It also means same secret is used for signing on one end as was used to verify on the other end, the same secret has to be used because verifying a signature requires that both ends generate the signature and both of the signature match. So no data is being encrypted, so not data in the JWT is sensitive and needs to be protected.

Given this context, both the refresh and access token are a simple JWT that can only be generated by the holder of the secret - if they are exposed they can be used to make malicious requests as long as they remain valid (nbf claim).

Essentially this type of JWT can be misused if exposed to impersonate the identity the secret that signed the JWT represents, without actually knowing the secret itself, until the nbf claim expires the token - and a refresh token is the mechanism to extend the nbf claim without having the secret (which would result in a new signature, because the nbf claim would change when used).

There is one protection from access token reuse, it is the nonce claim. If you do not currently use a nonce claim you can read about how OIDC have implemented and do he same in your app. But as you say, your app is stateless but hopefully the backend has a form of state to ensure no nonce reuse and prevent JWT signature reuse. For every nonce the JWT signature changes, therefore the access token changes and can be used only 1-time. So if stolen it is a race condition who uses the token first, which greatly minimises the risk but not a perfect solution.

Stof
  • 610
  • 7
  • 16