Overview
Duit uses Spring Security 6.x (included with Spring Boot 3.5) to provide comprehensive authentication and authorization. The security architecture follows industry best practices for password hashing, session management, and role-based access control.Security Configuration
SecurityConfig Class
Package:es.duit.app.config.SecurityConfig
The main security configuration class defines:
- HTTP security filter chain
- Password encoder
- Authentication and authorization rules
~/workspace/source/src/main/java/es/duit/app/config/SecurityConfig.java:1
Authentication
Password Encoding
All passwords are hashed using BCrypt:- Adaptive hashing (configurable work factor)
- Built-in salt generation
- Resistant to rainbow table attacks
- Industry standard for password storage
UserDetailsService
Custom implementation loads user details from the database: Class:CustomUserDetailsServicePackage:
es.duit.app.security
This service:
- Loads user by username (email)
- Converts AppUser to Spring Security UserDetails
- Loads user authorities (roles)
Form-Based Login
Configuration for the login form:- User submits credentials to
/login - Spring Security validates credentials
- On success →
LoginSuccessHandler - On failure →
LoginFailureHandler
Login Success Handler
Class:LoginSuccessHandlerPackage:
es.duit.app.configLocation:
~/workspace/source/src/main/java/es/duit/app/config/LoginSuccessHandler.java:1
Handles successful authentication:
- Extract authenticated username (email)
- Log successful login to
access_logtable - Redirect to
/home
Login Failure Handler
Class:LoginFailureHandlerPackage:
es.duit.app.configLocation:
~/workspace/source/src/main/java/es/duit/app/config/LoginFailureHandler.java:1
Handles failed authentication:
- Extract attempted username from request
- Log failed login attempt to
access_logtable (if username provided) - Redirect to
/login?error=true
Authorization
URL-Based Access Control
The security filter chain defines access rules for different URL patterns:Access Rules
| URL Pattern | Access Level | Roles |
|---|---|---|
/, /index | Public | None required |
/public/** | Public | None required |
/login, /signup, /register | Public | None required |
/css/**, /js/**, /img/**, /static/** | Public | None required (static resources) |
/privacy, /terms, /help | Public | None required |
/error, /error/** | Public | None required |
/admin/** | Admin only | ROLE_ADMIN |
/user/** | Users and admins | ROLE_USER, ROLE_ADMIN |
/professional/** | Professionals and admins | ROLE_PROFESSIONAL, ROLE_ADMIN |
| All other URLs | Authenticated | Any authenticated user |
Spring Security automatically adds “ROLE_” prefix to role names. When using
hasRole("ADMIN"), it checks for “ROLE_ADMIN” in the database.Role Hierarchy
The application defines four user roles:- ADMIN - Full system access
- USER - Regular client users
- PROFESSIONAL - Service providers
- MODERATOR - Content moderation (if implemented)
- Stored in
user_roletable - Referenced by
app_user.id_roleforeign key - See
UserRole.RoleNameenum at~/workspace/source/src/main/java/es/duit/app/entity/UserRole.java:22
Session Management
Remember Me
Persistent login functionality:- Cookie name parameter:
remember-me - Token validity: 86400 seconds (24 hours)
- Uses custom UserDetailsService
- Secret key:
duit-remember-me
Logout
Logout configuration:- Invalidate HTTP session
- Delete
JSESSIONIDcookie - Delete
remember-mecookie - Redirect to
/login?logout=true
Exception Handling
Access Denied
/error/403.
CSRF Protection
Enabling CSRF (Recommended for Production)
To enable CSRF protection, remove or modify the CSRF configuration:Access Logging
All login attempts (successful and failed) are logged to theaccess_log table via the AccessLogService.
Logged Information:
- User ID/email
- Timestamp
- Source IP address
- Success/failure status
- Security monitoring
- Audit trail
- Detecting brute force attacks
- User activity tracking
~/workspace/source/src/main/java/es/duit/app/entity/AccessLog.java:1
View-Level Security
Thymeleaf templates can use Spring Security expressions:thymeleaf-extras-springsecurity6 dependency
Security Best Practices
Implemented
- ✅ BCrypt password hashing with salt
- ✅ Role-based access control (RBAC)
- ✅ Session invalidation on logout
- ✅ Remember-me with expiration
- ✅ Access logging for audit trail
- ✅ Custom success/failure handlers
- ✅ Separate roles for different user types
Recommended for Production
- ⚠️ Enable CSRF protection
- ⚠️ Use HTTPS only (secure cookies)
- ⚠️ Implement rate limiting on login endpoint
- ⚠️ Add password complexity requirements
- ⚠️ Implement account lockout after failed attempts
- ⚠️ Add CAPTCHA for login form
- ⚠️ Secure actuator endpoints
- ⚠️ Configure Content Security Policy (CSP) headers
- ⚠️ Enable HTTP Strict Transport Security (HSTS)
Password Policy
Current validation in AppUser entity:This validates the hashed password length (BCrypt produces 60 characters). Add a separate validator for raw password complexity before hashing (e.g., min 8 characters, uppercase, lowercase, number, special character).
Method-Level Security
To enable method-level security annotations, add@EnableMethodSecurity to SecurityConfig:
Security Headers
Consider adding security headers in production:- Clickjacking (X-Frame-Options)
- XSS attacks (X-XSS-Protection)
- Man-in-the-middle attacks (HSTS)
- Unauthorized resource loading (CSP)
