JSON Web Token (JWT) based Authentication & Authorization in Web Application
Introduction
In web application, security is one of the major concern which must be handled properly with the proven technologies which does not compromise the security concern. Hence, it is always a challenge to provide highly secure web applications from user security and access management perspective.
If we discuss about the conventional approach being followed in web application, an authentication and authorization mechanism developed internally with help of web server session management capability. In this approach, user login with credential and a session is created in web application and same session is continued till user works in web application, once user want to exit from application, user invalidate the session created for him. Although this conventional approach is highly used and reliable but it can be used only with Monolithic application because it contains a user session to carry user identification, roles and responsibilities which is stored in server context. If we replicate the same applications to multiple instances, then user session must be required to associate with server only otherwise session will not be identified by other instance of same application. This was huge problem and a new mechanism is required to handle this situation.
Additionally, if we talk about the modern application design pattern like Micro-service design pattern, Nano-service design pattern, the common cross-cutting concerns like authentication, authorization, logging etc. are developed apart from the micro-services and there we need a authentication & authorization delegation mechanism which can work with all micro-services without having the complete authentication and authorization module with each micro-service.
JSON Web Token also known as JWT is a security token made with JSON specification which is created with data and optional signature with implied encryption algorithm to carry the user identification, issuer, issue time, issued to and optional access data. This token has also a sign created with secret or private key to check the integrity of token.
With JWT, there is token generation service (usually called authorization server) which validates the user identity (Normally with username and password and in some cases OTP/device authentication if Multi-Factor Authentication is available) and generates a JWT token to user/browser. Now, this generated token is used to access the protected web resources/endpoints by providing JWT token in Authorization header as Bearer token. When protected resource receive the Authorization header with Bearer JWT token, it parse and validate the signature and other fields, if token is valid, it grants requested resource access else provide Unauthorized/401 response to client.
We will discuss the JWT in details in following sections with proper use case.
Business Needs
When a web application designed with modern design patterns like micro-service design pattern where Authorization & Authentication are developed as separate micro-service and actual business logics are developed in separate micro-service. Therefore whenever Authentication is required, it is delegated to Authentication service, once authentication completed a token is generated for the user and this token is further used for other services access.
This authentication delegation requires a universally accepted and proven format for token which passes the security needs and serve the purpose.
JWT is especially designed by a group of authors for specifically this purpose and using this will solve the business challenges we face while creating web applications with modern design pattern and serve the security needs as well.
Technical Stack
JWT is designed for Web based application to carry user identification and other user details and is available for various programming language and development framework.
Below are list of programming languages which supports JWT and ready to libraries available for these languages:
- Java
- .Net
- Python
- Node.js
- Perl
- Ruby
- Elixir
- Erlang
- Go
- Haskell
- Haxe
- Rust
- Scala
- D
- Objective C
- Swift
- Clojure
- C and C++
- Delphi
- Php
- Kotlin
- Ada
- PowerShell
- Deno
Additionally, this is supported by all major Identity Providers (idPs) and Cloud vendors for authorization purpose. E.g.:
- Okta
- Auth0
- OneLogin
- Centrify
- ForgeRock
- GitHub
and so on.
With this article, a JWT based web application developed for demonstration purpose in following Tech Stack:
- Java
- Spring Boot with Embedded Tomcat, Spring Web and Spring Web Security
Audience
This article has been written to give ample understanding about the JWT, purpose and usage for modern web application design pattern. This also contains a Java based project developed in Spring Boot to give real example. It will be much helpful for developers, technical architects and product owners.
Problem
Suppose we have to develop a web application by following a modern design pattern like micro-services design pattern where authorization and authentication is handled by Identity Providers (idPs) to keep it separate. A proven identity and access storage mechanism is needed so that authentication is delated to idPs and once authentication completed, it again came back to actual resource with access validation.
Another problem is to use OAuth 2.0, for authorization while access the REST based endpoint with having Bearer token.
Both of the above discussed problem statements are highly useful in current time when Authentication and Authorization required a huge development as security is being increased day by day to protect the user identity and prevent from impersonation. Now, with most of the Cloud vendors and social media applications multi-factor authentication (MFA) is mandatory to avoid miss-use of account which adds additional identity validation apart from username and password e.g. One-Time-Password (OTP), Device Validation etc. These makes the Authorization mechanism complex and application owner wants to keep it in proven hands as vendors like Okta, Google, GitHub etc. which does user identity verification on behalf of actual application. Once user identity verification completed, it need to propagate to actual web application and here we need a proven format to delegate the user identity and access with proper security mechanism.
Solution
If we develop web application with micro-service design pattern where Authentication & Authorization is delegated to Identity Providers (idPs) or separate micro-service developed for Authentication and Authorization, in this case, once user authentication completed, the user identification details need to shared with other REST resource when they are access. For the purpose of storing user identity and access data, a ‘String of user details referred as token’ can be used and whenever user tries to access other protected web resources, the same token is provided.
This solution is usable, but need the token must have following:
- Ample amount of information must be present in token so that its complete identity can be validated e.g. issued to, issued by, issue time, expiry time, user id, unique token id, user access list and so on.
- The token must have security measure so that no-one can change it (either provide additional access or change its fields value)
- The format of token must be widely accepted or must have followed to a common specification so that different people working on different software products can understand and follow same specification rules
- A secure and reliable encryption mechanism must be present for token so that it cannot be ready by unknown entities
The above basic needs stands a common requirement for the vendors who wanted to provide the reliable and trusted user authentication & authorization products so they grouped together and started working on this. As a result first output came as Simple Web Token (SWT) and based on SWT an specification created.
Later on, it has been realized that it requires a huge amount of String processing each time for different purpose. Therefore, taking SWT as baseline, another specification created by using the JSON format and hence called JSON Web Token (JWT).
A JWT is a String token which having three portion separated by dot (.):
- Header — The header contains algorithm which has been used to generated signature and token type specifies which specification followed. There are some other header fields can be exist e.g. content type, message authentication code algorithm, key id, X509 certificate chain, critical etc.
- Payload — Payload is body of token which contains various fields also referred as Claims e.g. issuer, subject, audience, expiry time, not before time, issued at, unique jwt id and so on.
- Signature — The signature contains the Base64 encoded signature which has been generated by mentioned algorithm in header by using header and body of JWT token.
How it is secure?
When Authorization server generates the JWT token, it validates the user identity commonly with username and password, optionally with MFA e.g. OTP, Device Authentication etc. then loads user details like access list and generate JWT headers and body data. Based upon header and body, the signature is generated and appended to JWT token.
Now, when JWT token reached to business services, token is parsed by JWT libraries and obtained the header first, based upon header information signature is validated. If signature is valid, means there has not been any changes in token body which contains the claims. Since, claims are not checked then each field of claim is validated to ensure:
- expiry — it is check to ensure token is valid at the moment and is not expired
- issuer — check if the token has been issued by valid and trusted issuer
- issue to / subject — validate issue to valid subject
- not before — validate token is not used before its usage time
- audience — validate token is issue for specified audience or entities
Additionally, issuer identity can be verified with help of X509 certificates from headers and validate the certificate with issuing authorities.
In case of any change in JWT body which contains claims, the signature validation validation failed and easily identified corrupted JWT token.
Also, as additional layer, tokens can be encrypted with encryption mechanism (may be using public key / secrets) so that it does be parsed by unauthorized users to get claim information as well. Only targeted application can decrypt it and parse it with valid private key / secret.
By following above points, it makes secure way to store user identity and delegate to different services while making REST call to business services.
Example:
JWT Token:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Focus on dot (.) inside the JWT token which are separator for header, payload and signature.
There are some online tools to parse token e.g. https://jwt.io/ this can parse token and get different portion from JWT token. [Note: It supports only standard encoded JWT tokens]
Now, let’s understand what will be flow of application when JWT is used and how it is used. To use JWT, there are mainly two ways [there could be different ways as well but these are standard ways]:
- Simple JWT Authentication — In this approach, there will be one Authentication Server where users provide credential and get JWT token generated. Once tokens are generated, these same tokens are sent in Authorization header of REST calls as Bearer token. When business services gets the token, they validates, if token is not valid then unauthorized/401 response provided. If authorized then access to resource give and resource is served to client. Consider the below diagram which depicts the pictorial form for Simple JWT Authentication usages:
- JWT Authentication with Gateway — This approach is little advance and involve a Gateway in between services and client. In this approach, when user tries to access any application resource, the request goes via gateway. When request reach to gateway, it checks the Authorization header, if not available it redirects to Authentication server. If Authorization header is available it validates token, if validation passed then requested resource is served else return unauthorized/401 response to client. This approach is highly recommended because the business services are always used via gateway which already validate all security related concerns and then only allow request to land on actual business services. This enable developers not to write token validation with each business services and also protects services from direct attacks.
JWT is used internally with OAuth 2.0 for user authorization and resource access and is being supported by various social media vendors and Cloud vendors.
It opens a gateway to implement Single-Sign-On (SSO) for the application. Consider the scenarios, if we have an identity provider (idP) which issues the JWT token for multiple application (as the concept of Web master where multiple web applications are registered with a web master). In this case, when JWT token is issued, the list of audiences mentioned, and same token is used to other applications as well and user does not have to login again and again for each application. And these are the reasons JWT is becoming more popular with web applications.
Conclusion
JWT is highly useful, open and industry standard method for representing claims securely between two parties. This can be used in web application for authentication and authorization delegation when application is designed with modern micro-services design pattern or when application having common authentication server.
It is also highly useful for implementing Single-Sign-On (SSO) where user logins once and jump into multiple web applications without login separately.
The developers and architects can consider JWT for their web applications as it is highly secure and reliable. Using JWT, we can completely separate out the authentication and authorization mechanism from actual business services.
Links of Work on GitHub
A web based application has been developed to demonstrate the JWT example. This example has been developed with Java and Spring Boot framework using maven build tool.
Below is the link of source: https://github.com/siddhivinayak-sk/jwt-openid-oauth2.0-keycloak-kerberos-ntlm/tree/main/spring-boot-jwt
Checkout the code from given link, build and run it.
Prerequisite:
- Jdk 8 or later
- Apache maven 3.6 or later
Run below command to build:
mvn clean package -Dmaven.test.skip=true
Once build completed, please run (a jar file crated in target directory):
java -jar spring-boot-jwt-0.0.1.jar
Once it starts running, open browser and open below link to see swagger UI and endpoints created:
http://localhost:80/app/swagger-ui/
It has an endpoint to generate JWT token:
It will create a JWT token e.g.
{
"token": "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsImV4cCI6MTY0MDg1OTE1MywiaWF0IjoxNjQwODQxMTUzfQ.F0UCs_xfxMkdwaJ-uiDURC-0KyyhZKfnjCPhuhkeSJsj17gEQKEHAOOc2Tze1KQYZJfLJlh7AoWDOBHU_wf6_g"
}
Now, use postman or other rest client to make a call to protected endpoint which is http://localhost:80/app/hello. If you make call without valid token, it will give response code 401.
curl -X GET “http://localhost/app/hello" -H “accept: */*” -H “Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsImV4cCI6MTY0MDg1OTE1MywiaWF0IjoxNjQwODQxMTUzfQ.F0UCs_xfxMkdwaJ-uiDURC-0KyyhZKfnjCPhuhkeSJsj17gEQKEHAOOc2Tze1KQYZJfLJlh7AoWDOBHU_wf6_g”
It will return:
Hello World
References
- JWT — https://jwt.io/
- JWT IETF — https://datatracker.ietf.org/doc/html/rfc7519
- GitHub Source — https://github.com/siddhivinayak-sk/jwt-openid-oauth2.0-keycloak-kerberos-ntlm/tree/main/spring-boot-jwt
- Authentication in Web Application —
About the Author
Sandeep Kumar holds Master of Computer Application degree working as Java developer having 10+ years of working experience. He has experience design and development of enterprises applications in domains like education, content, laboratory, and banking; got various appreciation for his solutions including spot appreciation for Glassfish to JBoss migration project. He secured Google Cloud Developer certificate and participated into OCI trainings. He is a part of HCL-ERS platform as Sr. Lead developer.