JWT (JSON Web Token) is a widely used solution for securing REST APIs. Here's how you can implement JWT authentication in a Spring Boot application, step by step, as exemplified by the spring-security-jwt project.
1. Project Structure
- entity/: Contains the User entity (with JPA annotations).
- repository/: UserRepository to interact with the database.
- security/: Utility classes for generating, parsing, and validating JWT tokens.
- service/: Handles authentication logic, user details, filters, and security configuration.
2. pom.xml - Add Dependencies
To start, include the necessary dependencies in your Maven pom.xml:
- spring-boot-starter-security
- spring-boot-starter-web
- spring-boot-starter-data-jpa
- io.jsonwebtoken (for JWT operations)
- H2 Database for in-memory testing
Example:
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<!-- Add Spring Boot starters for security, web, JPA, H2 -->
3. User Entity and Repository
Define a User entity under entity/ folder, annotated with JPA annotations.
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
// getters & setters
}
Then, create a UserRepository interface extending JpaRepository in the repository/.
4. JWT Utility Class
The core part is the JwtUtil class (under security/), responsible for:
- Generating JWT tokens using a secret key.
- Validating and parsing tokens.
@Component
public class JwtUtil {
private String jwtSecret = "yourSecretKey";
private int jwtExpirationMs = 360000;
public String generateToken(Authentication authentication) {
// Implementation using io.jsonwebtoken library
}
public boolean validateJwtToken(String authToken) {
// Implementation to check token validity
}
public String getUserNameFromJwtToken(String token) {
// Parse claims and return username
}
}
5. Authentication Logic & UserDetailsService
Implement UserDetailsService that loads user-specific data.
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) {
// return user data from DB
}
}
6. JWT Authentication Filter
Create an AuthTokenFilter class (extends OncePerRequestFilter) that:
- Checks every incoming API request for a JWT token.
- Validates the token and sets authentication in the security context.
public class AuthTokenFilter extends OncePerRequestFilter {
@Autowired JwtUtil jwtUtil;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) {
// Extract, validate token, authenticate user
}
}
7. Spring Security Configuration
Configure security settings in WebSecurityConfig:
- Permit or restrict endpoints (e.g., allow /api/auth/** for authentication without JWT).
- Register JWT filter.
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired AuthTokenFilter authTokenFilter;
@Override
protected void configure(HttpSecurity http) {
http
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(authTokenFilter, UsernamePasswordAuthenticationFilter.class);
}
}
8. application.properties
Configure your application properties:
spring.application.name=spring-security-jwt
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=update
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
jwt.secret=YOUR_SECRET_KEY
jwt.expiration=360000
9. Endpoints for Authentication
Expose endpoints like /api/auth/login where users send credentials. Successful login returns a JWT token.
10. How It Works (Request Flow)
- User calls /api/auth/login with username/password.
- If credentials are valid, server generates JWT and returns it.
- For subsequent requests, the client includes the JWT in the Authorization: Bearer header.
- The JWT filter extracts and validates the token, and allows secured endpoints to process requests.
Conclusion
This project is a simple yet complete blueprint to implement JWT authentication in your Spring Boot app. The main steps are:
- Defining user entities and authentication services.
- Creating JWT utilities.
- Setting up security filters.
- Registering configurations to secure APIs.
Pro Tip: Always keep your JWT secret secure and consider adding roles/authorities to your tokens for advanced scenarios.
This flow will help any beginner understand and implement JWT in Spring Security projects.
GitHub Repository: spring-security-jwt
Top comments (0)