How to Build a Stateless JWT‑Based Authentication with Spring Boot and Shiro
This tutorial walks through creating a stateless authentication system for Spring Boot using Apache Shiro and JWT, covering required dependencies, Maven setup, data source simulation, token generation and verification, custom realm, filter, controller endpoints, and global exception handling.
Features
Fully annotation‑driven Shiro configuration for high flexibility.
Stateless authentication using JWT instead of cookies or HTTP sessions.
JWT keys support expiration time.
CORS support for cross‑origin requests.
Prerequisites
Before starting, you should be familiar with basic Spring Boot annotations ( Controller, RestController, Autowired), the concept of JSON Web Tokens and a Java JWT library, the Shiro 10‑minute tutorial, and an HTTP client such as PostMan.
Program Logic
POST /login with username and password; on success a signed JWT token is returned, otherwise a 401 error.
For every protected request the client must include the token in the Authorization header.
The backend validates the token; an invalid token results in a 401 response.
Token Encryption Details
The token carries the username claim.
An expiration time is set.
The user's password is used as the secret key for signing.
Token Validation Flow
Extract the username from the token.
Query the database for the user's password.
Verify the token using the password as the secret.
Maven Setup
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.inlighting</groupId>
<artifactId>shiro-study</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.5.8.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.5.7.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>Simple In‑Memory Data Source
A HashMap simulates a user table with fields username, password, role and permission. Example entries:
smith | smith123 | user | viewSigned-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Code Ape Tech Column
Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
