In this tutorial, we will walk through the process of creating a secure Spring Boot application with JSON Web Token (JWT) authentication. JSON Web Tokens are a popular choice for securing web applications, as they provide a stateless and secure way to handle user authentication and authorization.
Prerequisites
Before we get started, make sure you have the following prerequisites in place:
- Java Development Kit (JDK)
- Maven
- Your preferred Integrated Development Environment (IDE)
Step 1: Setting up a Spring Boot Project
The first step is to create a Spring Boot project. You can use Spring Initializer or your preferred IDE to set up a basic Spring Boot project. Make sure to include the necessary dependencies: spring-boot-starter-web
, spring-boot-starter-security
, and jjwt
for JWT support in your pom.xml
.
<!-- Your pom.xml file --> <dependencies> <!-- Spring Boot Starter Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Spring Security --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <!-- JSON Web Token (JWT) --> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> <version>0.11.2</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-impl</artifactId> <version>0.11.2</version> </dependency> </dependencies>
Step 2: Security Configuration
Create a configuration class to set up Spring Security and configure JWT authentication. In this class, we configure security rules and enable JWT-based authentication.
import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @EnableWebSecurity @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Autowired private PasswordEncoder passwordEncoder; @Bean public DaoAuthenticationProvider authenticationProvider() { DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); provider.setUserDetailsService(userDetailsService); provider.setPasswordEncoder(passwordEncoder); return provider; } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers("/api/auth/**").permitAll() .anyRequest().authenticated(); http.addFilterBefore(new JwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); } }
Step 3: User Management
To manage users, create a User
model and a UserRepository
. These will allow you to handle user registration and user retrieval.
Step 4: Auth Service
Implement a service class that handles user registration, login, and JWT generation. This service will use the UserRepository
to interact with the user data.
Step 5: JWT Utility
Create a utility class for JWT token generation and parsing. This class is essential for creating and validating tokens.
Step 6: Controller for Authentication
Develop a controller that handles authentication and authorization endpoints. In this example, we have endpoints for user registration and login.
@RestController @RequestMapping("/api/auth") public class AuthController { @Autowired private AuthService authService; @PostMapping("/register") public ResponseEntity<?> registerUser(@RequestBody UserRegistrationRequest userRegistrationRequest) { authService.register(userRegistrationRequest); return ResponseEntity.ok("User registered successfully"); } @PostMapping("/login") public ResponseEntity<?> loginUser(@RequestBody UserLoginRequest userLoginRequest) { String jwt = authService.login(userLoginRequest); return ResponseEntity.ok(new JwtResponse(jwt)); } }
Step 7: JWT Filter
Create a JWT filter that validates and extracts JWTs from incoming requests. This filter is essential for authenticating users based on the provided token.
Step 8: Secure Your Application
You can now secure other parts of your Spring Boot application by adding appropriate @PreAuthorize
annotations to your controller methods or using other Spring Security features. This allows you to control access to specific parts of your application based on user roles and permissions.
In this tutorial, we’ve created a Spring Boot application with JWT authentication, which provides a secure and stateless way to handle user authentication and authorization. This is a foundational step in building a secure web application, and you can expand upon this foundation to meet the specific needs of your project.
Remember that this is a simplified example, and in a production environment, you should consider additional features like refresh tokens, user roles, and proper exception handling for a complete and secure application.
Happy coding!