What is JWT ? How it works ? How can it keep our applications secure?
JSON Web Tokens has become the favourite choice among modern developers when implementing user authentication. Let’s understand what JWT is and how it works, specifically in the context of securing web applications.
There is an open industry standard specification called RFC 7519 that outlines how a JWT should be structured and how to use it for exchanging the information between parties as JSON objects.
Authentication is basically what happens when users sign-in. We check the user’s identity based on credentials like username/password.
Authorization, on the other hand, checks if the above-validated user is able to access specified modules or not
There are multiple ways that web applications can manage sessions and two of the popular ways is by using the tokens.
Session Tokens
In this mechanism, the server will create a session for the user after the user is successfully authenticated. The session will have an unique identifier, which is stored as a cookie on the users browser. While the user stays logged in, the cookie would be sent along with every subsequent request.
The server parses the cookie and then compares the session id against the session information stored in the memory or data store to verify the user’s identity and provides the user context to the application.
The biggest problem with this approach is, it assumes that, there is always just one monolithic server web application. That used to be the case typically in the past. But that’s no longer the case these days as we live in micro services world.
There would be multiple servers that share the load that sit behind a load balancer. When a request comes in, the load balancer decides which server to route the request. The user could have had their login request routed to one server, but the next request goes through the load balancer and may land on a different server. Now this new server has no idea about the previous interaction.
Being a techie, we may find a solution for it. Let’s say, we introduce a shared cache that all these servers persist and look up user session information which will solve the problem.
JSON Web Tokens
In this mechanism, the authentication server will authenticate the user and generate a JWT which will have all the required information. It will be sent back to the client for later usage. This is more scalable solution as JWT is stateless, which means, the user state is never stored on the server but the state is stored inside the token itself.
If the user is making a subsequent request to the application, the JWT needs to be added with the request. The application server will be configured to be able to check whether the incoming JWT is exactly what was created by the authentication server.
Let’s look at the format of the JWT to understand it better. A JSON Web Token consists of 3 sections separated by periods.
Header
The header section typically contains 2 details — the type of token (JWT in this case) and the hashing algorithm used by the token such as RSA, HMAC, or SHA256. The default algorithm used is HS256.
Payload
The payload section contains actual data pertaining to a user is what we call as claims. The claims can be of 3 types:
Reserved Claims
These are some pre-defined claims which are not mandatory but recommended to use it as a best practise. These claims help the application judge the authenticity of the token. Listing few of them for sample are iss (issuer), sub (subject), exp (expiration time) etc.
Public Claims
These can be defined based on the requirements by those using JWTs. As it’s a public claims, to avoid issues they should be defined in the IANA JSON Web Token Registry.
Private Claims
These are the custom claims created to share information between parties that agree on using them. Listing few of them as sample are employment type, department name etc.
If anyone is interested to read more about claims, you can read it over here.
Signature
The signature is the most important part of a JSON Web Token. It is calculated by encoding the header and payload using Base64URL Encoding and concatenating them with a period as separator, which is then run through the cryptographic algorithm. Please remember when the header or payload changes, the signature has to be calculated again.
// Signature Algorithm
jwtData = base64urlEncode(header) + "." + base64urlEncode(payload)
signature = HMAC(jwtData, secret_salt)
// Token Generation
token = encodeBase64Url(header) + "." + encodeBase64Url(payload) + "." + encodeBase64Url(signature)
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwiaXNzIjoiQmhhcmdhdiBJbmMuIiwiZXhwIjoxNjEzOTM4Mzg3LCJpYXQiOjE2MTM5MjAzODd9.XblnkCqOUdtjLIg2pJcN_7gXUc7nSHIuXnBwin8hSeQ
What’s next ?
Shhh! Let me tell you a secret. Go to jwo.io website, copy the above JWT and paste it in the encoded section of the online debugger. Voila, you could see all the data stored in the token. Now you will have a question on your mind, what the heck, how is this secure? 🤔
Please note that, JWT’s are encoded but not encrypted. It is a mechanism by which you can verify that the data is not tampered and has come from the trusted source.
The two open industry standards that describe the security features of JWT are RFC 7515 for JSON Web Signature and RFC 7516 for JSON Web Encryption.
JSON Web Signature
The purpose of a signature is to allow one or more parties to establish the authenticity of the JWT. Now if you remember the signature is basically the encoded header and payload concatenated with a period and then run through a hashing algorithm with a secret key.
The signature attached at the end helps us to determine if the JWT has been tampered with because for any change in the data the signature will change. A signature, however does not prevent third parties from reading the contents of the JWT.
JSON Web Encryption
JWS provides us to establish the authenticity of the JWT contents, where as JWE provides a way to keep the contents of the JWT unreadable to third parties.
An encrypted JWT, can use two cryptographic schemes — a shared secret scheme or a public/private-key scheme.
Conclusion
JWT is a modern and robust solution to authenticate and authorise users and sharing sensitive information while not maintaining state. A JWT is made of three parts — header, payload and signature. Sending JWTs in cookies instead of in the header, shortening their expiration time and using refresh tokens to issue new access tokens are some of the security measures we can take to guarantee the security of our application, its users and their data.
0 comments:
Post a Comment