This demo project illustrates the process of JWT (JSON Web Token) signature validation in a mvc Java application, focusing on security best practices and authentication mechanisms. The project used in this article https://medium.com/@dimavilda/validating-jwt-signatures-what-happens-under-the-hood-44d91db54c2ahelps as an example that help engineers to understand the technical and mathematical details of JWT validation process in Java
- Java 17
- Spring Boot 3.1.5
- Keycloak 22.0.1 - Open-source identity and access management
- Docker Compose - For containerized infrastructure
- jjwt (Java JWT) - JWT parsing and validation library
- Automated JWT token validation
- Key ID (kid) claim extraction and verification
- MD5 hash-based key identification
- Secure public key validation
- Comprehensive error handling
- Java Development Kit (JDK) 17+
- Maven
- Docker
- Docker Compose
git clone https://github.com/yourusername/jwt-validation-demo.git
cd jwt-validation-demodocker-compose up -d- Open Keycloak Admin Console at
http://localhost:8080 - Login with credentials:
- Username:
admin - Password:
admin
- Username:
- Create a new realm (e.g.,
jwt-demo-realm) - Create a new client (e.g.,
demo-app) with the following configurations:- Client type:
OpenID Connect - Client authentication:
On - Standard flow:
On - Direct access grants:
On
- Client type:
- In the client settings:
- Set Valid redirect URIs to
http://localhost:3000/* - Generate a client secret
- Set Valid redirect URIs to
- Create a new user:
- Navigate to Users section
- Click "Add user"
- Set a username
- Go to Credentials tab
- Set a password
- Disable "Temporary" to allow immediate login
# Build the project
mvn clean package# Run the application
mvn spring-boot:runThe application server will start on port 3000
- Use this api to obtain an access token from Keycloak:
curl -X POST http://localhost:8080/realms/{YOUR_REALM_NAME}/protocol/openid-connect/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=..." \
-d "client_secret=..." \
-d "username=..." \
-d "password=..." \
-d "grant_type=password"This will return a JSON response containing an access_token.
Use the obtained access token to test the validation endpoint:
curl -X GET http://localhost:3000/demo/data \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN_HERE"The application performs several critical steps:
- Extract token header and claims
- Verify Key ID (kid) claim
- Validate token signature using public key
- Check token integrity and authenticity
Contributions, issues, and feature requests are welcome!