Reputation: 634
I am trying to implement and take advantage of JWT (JSON Web Token)
for securing my system. I got the part of JWT to be tamper-proof. I went to lot of discussions on how JWT can be securely implemented but still I am getting little more confused.
First of all, what I've decided to do is use 2 tokens (a refresh token and an access token).
(1) should i create single access token or as i thought should use different access token for different kinds of requests.
My logical flow would be something like:
A) User logs in with valid username and password ==> Server validates the parameters and on success create a refresh token(RT) and sends RT back to user.
B) User when accessing a protected api in my server, first sends the refresh token(RT) and if valid server sends back an access token(AT) to access that api.
C) User sends access token to the protected api and upon successful validation sends back protected resources to user as required.
(2) But still I feel like I am lacking something from security point of view. Like if somebody else gets hands on refresh token they can create access token right?
(3) Also like is the access token even needed here by implementing (B) and (C).
I would greatly appreciate your help.
Upvotes: 1
Views: 836
Reputation: 820
If a bad actor gets their hands on a refresh token, they cannot create and sign new tokens, but they can extend the lifetime of current tokens into the foreseeable future. This poses a security risk, obviously - it is up to you if you want to take that risk.
You will need an access token during some point of the flow you are describing.
You could forget about supporting refresh tokens all together. it is very difficult to stop a bad actor from doing damage if they get their hands on a refresh token.
I would advise creating one type of access token and to use that to grant access to resources on your server. One strategy you could take is the following:
Your auth server will will need to be the single issuer of JWTs to your microservices. So, when a user logs in and successfully authenticates, your auth server will issue a JWT signed with a private key (signing MUST be asymmetric - RS256 is one example) you keep on the auth server only; do not give this private key to other microservices that you wish to validate JWTs inside of. What you can do is derive a public key based on the private key you sign your tokens with and publish that to an endpoint on your auth server that requires no authentication - the public key will be represented in the form of a JWK (see link to spec). Google does something similar here. Then, in each of your microservices, you will need to devise a way to make a GET request to the public key endpoint on your auth server every X minutes and cache the public key in each microservice.
Then whenever a request comes into one of your microservices, you grab the JWT, check its validity, and grant access/authorization if the token is valid. The beauty of using a private/public key pair and asymmetric key signing is that you can validate a token based on the public key alone, but not sign it. So as long as each service has the public key from your /cert endpoint, they can validate a token without ever needing to talk to the auth server or knowing the private key.
This will require a little more work up front, but will yield you massive amount of ease, flexibility, and peace of mind in the future knowing only one source knows your private key.
I suggest using this library to do JWT validation if your implementation is in Java.
The overall architecture will end up looking something like this:
Upvotes: 1