I am considering to use JWT. In the jwt.io example I am seeing the following information in the payload data:
"admin": true
Admin can be considered as a Role, hence my question. Is setting the role in the token payload a habitual/good practice? Given that roles can be dynamically modified, I'm quite interrogative.
Generate a JWT application in your authentication provider of choice, and copy the application's client secret. Go to your Netlify site settings under Access control > Visitor access > Password / JWT secret. Select Set JWT secret, and enter the secret from your authentication provider.
Although JWT does eliminate the database lookup, it introduces security issues and other complexities while doing so. Security is binary—either it's secure or it's not. Thus making it dangerous to use JWT for user sessions.
To keep them secure, you should always store JWTs inside an httpOnly cookie. This is a special kind of cookie that's only sent in HTTP requests to the server. It's never accessible (both for reading or writing) from JavaScript running in the browser.
The official JWT site explicitly mentions "authorization" (in contrast to "authentication") as a usecase for JWTs:
When should you use JSON Web Tokens? Authorization: This is the most common scenario for using JWT. Once the user is logged in, each subsequent request will include the JWT, allowing the user to access routes, services, and resources that are permitted with that token. Single Sign On is a feature that widely uses JWT nowadays, because of its small overhead and its ability to be easily used across different domains.
That being said, from a security-perspective you should think twice whether you really want to include roles or permissions in the token.
(The text below can be understood as a more "in-depth" follow up to the rather short-kept accepted answer)
Once you created and signed the token you grant the permission until the token expires. But what if you granted admin permissions by accident? Until the token expires, somebody is now operating on your site with permissions that were assigned by mistake.
Some people might argue that the token is short-lived, but this is not a strong argument given the amount of harm a person can do in short time. Some other people advocate to maintain a separate blacklist database table for tokens, which solves the problem of invalidating tokens, but adds some kind of session-state tracking to the backend, because you now need to keep track of all current sessions that are out there – so you would then have to make a db-call to the blacklist every time a request arrives to make sure it is not blacklisted yet. One may argue that this defeats the purpose of "putting the roles into the JWT to avoid an extra db-call" in the first place, since you just traded the extra "roles db-call" for an extra "blacklist db-call".
So instead of adding authorization claims to the token, you could keep information about user roles and permissions in your auth-server's db over which you have full control at any time (e.g. to revoke a certain permission for a user). If a request arrives, you fetch the current roles from the auth-server (or wherever you store your permissions).
By the way, if you have a look at the list of public claims registered by the IANA, you will see that these claims evolve around authentication and are not dealing with what the user is allowed to do (authorization).
So in summary you can...
add roles to your JWT if (a) convenience is important to you and (b) you want to avoid extra database calls to fetch permissions and (c) do not care about small time windows in which a person has rights assigned he shouldn't have and (d) you do not care about the (slight) increase in the JWT's payload size resulting from adding the permissions.
add roles to your JWT and use a blacklist if (a) you want to prevent any time windows in which a person has rights assigned he shouldn't have and (b) accept that this comes at the cost of making a request to a blacklist for every incoming request and (c) you do not care about the (slight) increase in the JWT's payload size resulting from adding the permissions.
not add roles to your JWT and fetch them on demand if (a) you want to prevent any time windows in which a person has rights assigned he shouldn't have or (b) avoid the overhead of a blacklist or (c) avoid increasing the size of your JWT payload to increase slightly and (d) if you accept that this comes at the cost of sometimes/always querying the roles on incoming requests.
Nothing stops you from creating claims to store extra information in your token if they can be useful for your client.
However I would rely on JWT only for authentication (who the caller is). If you need to perform authorization (what the caller can do), look up the caller roles/permissions from your persistent storage to get the most updated value.
For short-lived tokens (for example, when propagating authentication and authorization in a microservices cluster), I find it useful to have the roles in the token.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With