Complete Spring Boot Security Guide - Learn modern security practices with JWT Authentication, Email Verification, Two-Factor Authentication (2FA), and SMTP integration.
- ๐ฏ About This Project
- โจ Features
- ๐ ๏ธ Technologies
- ๐ Requirements
- โก Quick Start
- ๐ง Configuration
- ๐ API Documentation
- ๐๏ธ Project Architecture
- ๐ Detailed Code Review
- ๐ฑ Postman Collection
- ๐งช Testing
- ๐ Learning Resources
- ๐ค Contributing
- ๐ License
This project is a complete guide for developers who want to learn Spring Boot Security implementation in modern web applications. It's designed for real-world scenarios and shows security best practices.
- How to implement JWT (JSON Web Token) authentication
- How to set up an Email verification system
- How to integrate Two-Factor Authentication (2FA)
- How to configure Spring Security
- How to send emails with SMTP
- How to integrate PostgreSQL database
- What are the Security best practices
- JWT Token-based Authentication
- Role-based Authorization (USER, ADMIN)
- Password Encryption (BCrypt)
- Session Management (Stateless)
- Email Verification system
- SMTP Configuration (Gmail)
- HTML Email Templates
- Email Token Management
- Google Authenticator integration
- QR Code generation
- TOTP (Time-based One-Time Password)
- Setup and Verification endpoints
- CORS configuration
- Input Validation
- Exception Handling
- Security Headers
- Spring Boot 3.5.3 - Framework
- Spring Security 6 - Security
- Spring Data JPA - ORM
- Spring Boot Mail - Email
- PostgreSQL - Database
- JWT (jjwt 0.11.5) - Token management
- Google Authenticator (1.5.0) - 2FA
- ZXing (3.5.1) - QR Code generation
- BCrypt - Password hashing
- Lombok - Boilerplate code reduction
- Maven - Dependency management
- H2 - Test database
- Postman - API testing
- Java 17+
- Maven 3.6+
- PostgreSQL 12+
- IDE (IntelliJ IDEA, Eclipse, VS Code)
- Gmail account
- App Password (for Gmail accounts with 2FA enabled)
git clone https://github.com/sogutemir/spring-boot-security.git
cd spring-boot-securityCREATE DATABASE securityExampleDB;spring:
datasource:
url: jdbc:postgresql://localhost:5432/securityExampleDB
username: your_username
password: your_password
mail:
username: your_email@gmail.com
password: your_app_passwordmvn clean install
mvn spring-boot:run- API Base URL:
http://localhost:8080 - Health Check:
http://localhost:8080/actuator/health
spring:
datasource:
url: jdbc:postgresql://localhost:5432/securityExampleDB
username: postgres
password: 123456
driver-class-name: org.postgresql.Driver
jpa:
hibernate:
ddl-auto: update
show-sql: true
properties:
hibernate:
dialect: org.hibernate.dialect.PostgreSQLDialect
format_sql: truejwt:
secret: myVeryLongSecretKeyThatIsAtLeast64BytesLongForHS512Algorithm
expiration: 86400000 # 24 hoursspring:
mail:
host: smtp.gmail.com
port: 587
username: your_email@gmail.com
password: your_app_password
properties:
mail:
smtp:
auth: true
starttls:
enable: truePOST /api/auth/register
Content-Type: application/json
{
"email": "user@example.com",
"password": "securePassword123",
"firstName": "John",
"lastName": "Doe"
}POST /api/auth/login
Content-Type: application/json
{
"email": "user@example.com",
"password": "securePassword123"
}POST /api/auth/verify-email?token=your_verification_tokenPOST /api/auth/2fa/setup
Authorization: Bearer your_jwt_tokenPOST /api/auth/2fa/verify-setup
Authorization: Bearer your_jwt_token
Content-Type: application/json
{
"code": "123456"
}POST /api/auth/2fa/verify
Content-Type: application/json
{
"email": "user@example.com",
"code": "123456"
}src/main/java/com/babili/springbootsecurity/
โโโ ๐ SpringBootSecurityApplication.java
โโโ โ๏ธ config/
โ โโโ SecurityConfig.java
โโโ ๐ฎ controller/
โ โโโ AuthController.java
โ โโโ TwoFactorAuthController.java
โโโ ๐ฆ dto/
โ โโโ AuthResponse.java
โ โโโ LoginRequest.java
โ โโโ RegisterRequest.java
โ โโโ MessageResponse.java
โ โโโ TwoFactorSetupResponse.java
โ โโโ TwoFactorVerificationRequest.java
โโโ ๐๏ธ entity/
โ โโโ User.java
โ โโโ Role.java
โ โโโ EmailVerificationToken.java
โโโ โ exception/
โ โโโ GlobalExceptionHandler.java
โ โโโ InvalidTokenException.java
โ โโโ TokenExpiredException.java
โ โโโ UserAlreadyExistsException.java
โโโ ๐๏ธ repository/
โ โโโ UserRepository.java
โ โโโ EmailVerificationTokenRepository.java
โ โโโ CustomCredentialRepository.java
โโโ ๐ security/
โ โโโ AuthTokenFilter.java
โ โโโ UserDetailsServiceImpl.java
โ โโโ UserPrincipal.java
โโโ โ๏ธ service/
โ โโโ AuthService.java
โ โโโ UserService.java
โ โโโ EmailService.java
โ โโโ EmailVerificationService.java
โ โโโ RegistrationService.java
โ โโโ TwoFactorAuthService.java
โโโ ๐ ๏ธ util/
โโโ JwtUtils.java
graph TD
A[User Registration] --> B[Validate Input]
B --> C[Hash Password]
C --> D[Save User to DB]
D --> E[Generate Verification Token]
E --> F[Send Verification Email]
F --> G[User Clicks Email Link]
G --> H[Verify Token]
H --> I[Activate Account]
graph TD
A[Login Request] --> B[Validate Credentials]
B --> C{2FA Enabled?}
C -->|No| D[Generate JWT]
C -->|Yes| E[Request 2FA Code]
E --> F[Verify 2FA Code]
F --> D[Generate JWT]
D --> G[Return Auth Response]
The SecurityConfig.java file contains the application's security configuration:
@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true)
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.cors(cors -> cors.disable())
.csrf(csrf -> csrf.disable())
.sessionManagement(session ->
session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated())
.addFilterBefore(authenticationJwtTokenFilter(),
UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}The JwtUtils.java file manages JWT token operations:
@Component
public class JwtUtils {
private static final Logger logger = LoggerFactory.getLogger(JwtUtils.class);
@Value("${jwt.secret}")
private String jwtSecret;
@Value("${jwt.expiration}")
private int jwtExpirationMs;
public String generateJwtToken(Authentication authentication) {
UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal();
return Jwts.builder()
.setSubject(userPrincipal.getEmail())
.setIssuedAt(new Date())
.setExpiration(new Date((new Date()).getTime() + jwtExpirationMs))
.signWith(SignatureAlgorithm.HS512, jwtSecret)
.compact();
}
}The EmailService.java file handles email sending operations:
@Service
public class EmailService {
private final JavaMailSender mailSender;
public void sendVerificationEmail(String to, String token) {
try {
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
helper.setTo(to);
helper.setSubject("Email Verification - Security Example App");
String verificationUrl = frontendUrl + "/verify-email?token=" + token;
String htmlContent = buildVerificationEmailContent(verificationUrl);
helper.setText(htmlContent, true);
mailSender.send(message);
} catch (MessagingException e) {
throw new RuntimeException("Failed to send verification email", e);
}
}
}The TwoFactorAuthService.java file manages 2FA operations:
@Service
public class TwoFactorAuthService {
private static final String ISSUER = "SecurityExampleApp";
private final GoogleAuthenticator gAuth;
public TwoFactorSetupResponse setupTwoFactor(String email) {
User user = userService.findByEmail(email);
GoogleAuthenticatorKey key = gAuth.createCredentials();
String secret = key.getKey();
// QR Code generation
String qrCodeUrl = GoogleAuthenticatorQRGenerator.getOtpAuthURL(
ISSUER, email, key);
return TwoFactorSetupResponse.builder()
.secret(secret)
.qrCodeUrl(qrCodeUrl)
.qrCodeImage(generateQRCodeImage(qrCodeUrl))
.build();
}
}The project includes a Spring_Boot_Security_API_Collection.postman_collection.json file. This collection contains the following tests:
- User Registration - New user registration
- Email Verification - Email verification
- User Login - User login
- 2FA Setup - Two-factor authentication setup
- 2FA Verification - Two-factor authentication verification
- Protected Endpoints - Protected endpoint tests
- Open Postman
- Click the Import button
- Select Upload Files option
- Choose the
Spring_Boot_Security_API_Collection.postman_collection.jsonfile - Click Import
mvn testmvn verify-
User Registration
- Use the
/api/auth/registerendpoint - Check your email
- Use the
-
Email Verification
- Click the link in the email or manually send the token
-
Login
- Use the
/api/auth/loginendpoint - Get the JWT token
- Use the
-
2FA Setup
- Use the
/api/auth/2fa/setupendpoint - Add the QR code to Google Authenticator
- Use the
-
2FA Login
- Try to login with a 2FA-enabled account
- Get the code from Google Authenticator
- JWT.io - JWT debugger and libraries
- RFC 7519 - JWT Specification
This is an open-source educational project. We welcome your contributions!
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- ๐ Bug fixes
- โจ New features
- ๐ Documentation improvements
- ๐งช Test coverage
- ๐ง Performance optimizations
- ๐ Internationalization
This project is licensed under the MIT License. See the LICENSE file for details.
If this project helped you, please support it by giving it a โญ!
- GitHub: @sogutemir
- LinkedIn: Sogut Emir
- Mail: muhammet.sogut@tubitak.gov.tr
For questions, you can open an issue or contact me via email: muhammet.sogut@tubitak.gov.tr
Happy Coding! ๐
Enter the world of Spring Boot Security with this comprehensive project and become an expert in security topics for modern web applications!