Overview
The Furniture API implements security measures including CORS configuration, SSL requirements for database connections, and service registry authentication through Netflix Eureka. This document covers the current security implementation and best practices.
CORS Configuration
Cross-Origin Resource Sharing
The API implements CORS to control which frontend applications can access the API endpoints.
Configuration : CorsConfig.java
@ Configuration
public class CorsConfig implements WebMvcConfigurer {
@ Override
public void addCorsMappings ( CorsRegistry registry ) {
registry . addMapping ( "/api/**" )
. allowedOrigins ( "https://tu-frontend.com" )
. allowedMethods ( "GET" , "POST" , "PUT" , "DELETE" , "PATCH" , "OPTIONS" )
. allowedHeaders ( "*" );
}
}
CORS Policy Details
Allowed Paths : /api/** (all API endpoints)
Allowed Origins : https://tu-frontend.com
Allowed Methods :
GET - Read operations
POST - Create operations
PUT - Full update operations
DELETE - Delete operations
PATCH - Partial update operations
OPTIONS - Preflight requests
Allowed Headers : All headers (*)
Credentials : Not enabled by default
The wildcard * for allowed headers is permissive. In production, consider restricting to specific headers like Content-Type, Authorization, and X-Requested-With.
Preflight Requests
Browsers automatically send OPTIONS requests before actual requests when:
Using methods other than GET, HEAD, or POST
Including custom headers
Using Content-Type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain
The CORS configuration handles these preflight requests automatically.
Show Example preflight request/response
Request :OPTIONS /api/products HTTP / 1.1
Host : api.furniture.com
Origin : https://tu-frontend.com
Access-Control-Request-Method : POST
Access-Control-Request-Headers : Content-Type
Response :HTTP / 1.1 200 OK
Access-Control-Allow-Origin : https://tu-frontend.com
Access-Control-Allow-Methods : GET,POST,PUT,DELETE,PATCH,OPTIONS
Access-Control-Allow-Headers : *
Production Considerations
The configuration includes a comment in Spanish: “evitar '' en producción” (avoid ' ' in production), indicating the current setup should be hardened before deployment.
Recommendations for production :
Multiple Origins : Support multiple frontend domains
. allowedOrigins (
"https://tu-frontend.com" ,
"https://www.tu-frontend.com" ,
"https://admin.tu-frontend.com"
)
Specific Headers : Limit allowed headers
. allowedHeaders ( "Content-Type" , "Authorization" , "X-Request-ID" )
Enable Credentials : If using cookies or authentication
When allowCredentials(true) is enabled, you cannot use wildcard * for origins. You must specify exact domain names.
Database Security
SSL/TLS Encryption
The PostgreSQL database connection requires SSL encryption:
spring.datasource.url =jdbc:postgresql://...? sslmode =require& channelBinding =require
Security Features :
sslmode=require - Forces encrypted connections
channelBinding=require - Prevents man-in-the-middle attacks
Connection pooling through Neon pooler
All data in transit between the application and database is encrypted using TLS. Neon uses certificate-based authentication for added security.
Database Credentials
The current application.properties file contains hardcoded database credentials. This is a security risk and should be addressed before production deployment.
Recommended approach :
Environment Variables : Store credentials externally
spring.datasource.url =${DATABASE_URL}
Secret Management : Use services like:
AWS Secrets Manager
HashiCorp Vault
Kubernetes Secrets
Spring Cloud Config Server
Profile-Specific Configuration : Separate configs for dev/prod
# application-prod.properties
spring.datasource.url =${DATABASE_URL}
Service Discovery Security
Eureka Client Configuration
The microservice registers with Netflix Eureka for service discovery:
eureka.client.service-url.defaultZone =https://furniture-eureka-server.onrender.com/eureka
eureka.instance.prefer-ip-address =true
eureka.client.fetch-registry =true
eureka.client.register-with-eureka =true
Security considerations :
Eureka server uses HTTPS protocol
Service registration is automatic on startup
IP address is preferred for service-to-service communication
The @EnableDiscoveryClient annotation in FurnitureApplication.java enables automatic service registration with Eureka, allowing other microservices to discover this API.
API Security (Not Yet Implemented)
The current implementation does not include authentication or authorization mechanisms. All endpoints are publicly accessible.
Recommended Security Additions
For production deployment, consider implementing:
1. Spring Security
Add Spring Security dependency:
< dependency >
< groupId > org.springframework.boot </ groupId >
< artifactId > spring-boot-starter-security </ artifactId >
</ dependency >
2. JWT Authentication
Implement token-based authentication:
@ Configuration
@ EnableWebSecurity
public class SecurityConfig {
@ Bean
public SecurityFilterChain filterChain ( HttpSecurity http ) throws Exception {
http
. csrf (). disable ()
. authorizeHttpRequests (auth -> auth
. requestMatchers ( "/api/public/**" ). permitAll ()
. requestMatchers ( "/api/**" ). authenticated ()
)
. oauth2ResourceServer (OAuth2ResourceServerConfigurer :: jwt);
return http . build ();
}
}
3. OAuth 2.0 / OpenID Connect
Integrate with identity providers:
Auth0
Okta
Keycloak
AWS Cognito
4. API Key Authentication
For service-to-service communication:
@ Component
public class ApiKeyFilter extends OncePerRequestFilter {
@ Override
protected void doFilterInternal ( HttpServletRequest request ,
HttpServletResponse response ,
FilterChain filterChain ) {
String apiKey = request . getHeader ( "X-API-Key" );
// Validate API key
}
}
Actuator Security
Spring Boot Actuator endpoints are currently enabled without security:
spring-boot-starter-actuator
Actuator endpoints can expose sensitive information about your application. They should be secured before production deployment.
Secure actuator endpoints :
# Expose only health endpoint
management.endpoints.web.exposure.include =health,info
management.endpoint.health.show-details =when-authorized
@ Configuration
public class ActuatorSecurityConfig {
@ Bean
public SecurityFilterChain actuatorSecurity ( HttpSecurity http ) {
http . requestMatcher ( EndpointRequest . toAnyEndpoint ())
. authorizeHttpRequests (auth -> auth
. requestMatchers ( EndpointRequest . to ( "health" )). permitAll ()
. anyRequest (). hasRole ( "ADMIN" )
);
return http . build ();
}
}
The application includes Hibernate Validator for bean validation:
< dependency >
< groupId > org.hibernate.validator </ groupId >
< artifactId > hibernate-validator </ artifactId >
</ dependency >
Use validation annotations on DTOs and entities:
public class ProductRequest {
@ NotBlank ( message = "Product name is required" )
@ Size ( min = 3 , max = 100 )
private String name ;
@ NotNull
@ DecimalMin ( value = "0.01" )
private Double price ;
@ Pattern ( regexp = "^[A-Z0-9-]+$" )
private String sku ;
}
Validation prevents SQL injection and data integrity issues by rejecting invalid input before it reaches the database layer.
Implement security headers to protect against common web vulnerabilities:
@ Configuration
public class SecurityHeadersConfig {
@ Bean
public WebSecurityCustomizer webSecurityCustomizer () {
return (web) -> web . ignoring (). requestMatchers ( "/swagger-ui/**" );
}
@ Bean
public SecurityFilterChain headers ( HttpSecurity http ) throws Exception {
http . headers (headers -> headers
. contentSecurityPolicy ( "default-src 'self'" )
. xssProtection (xss -> xss . headerValue ( XXssProtectionHeaderWriter . HeaderValue . ENABLED_MODE_BLOCK ))
. frameOptions (frame -> frame . deny ())
. httpStrictTransportSecurity (hsts -> hsts
. includeSubDomains ( true )
. maxAgeInSeconds ( 31536000 )
)
);
return http . build ();
}
}
Best Practices
Development Environment
Use separate database credentials for development
Enable detailed error messages for debugging
Use HTTP for local development
Keep Swagger UI enabled for API testing
Production Environment
Never commit credentials to source control
Use environment variables or secret managers
Enable HTTPS only (disable HTTP)
Implement rate limiting
Add request logging and monitoring
Disable detailed error messages
Restrict CORS to specific domains
Secure all actuator endpoints
Implement authentication and authorization
Use API versioning
Add request/response encryption for sensitive data
Consider using Spring Profiles (@Profile("prod")) to automatically apply production security configurations when the production profile is active.
Future Security Enhancements
Recommended roadmap for security improvements:
Phase 1 : Implement JWT authentication
Phase 2 : Add role-based access control (RBAC)
Phase 3 : Implement rate limiting and DDoS protection
Phase 4 : Add API audit logging
Phase 5 : Implement field-level encryption for sensitive data
Phase 6 : Add IP whitelisting for admin endpoints
Phase 7 : Implement API versioning with security policies per version
Show Example RBAC implementation
@ PreAuthorize ( "hasRole('ADMIN')" )
@ DeleteMapping ( "/api/products/{id}" )
public ResponseEntity < Void > deleteProduct (@ PathVariable Integer id) {
productService . delete (id);
return ResponseEntity . noContent (). build ();
}
@ PreAuthorize ( "hasAnyRole('USER', 'ADMIN')" )
@ GetMapping ( "/api/products" )
public ResponseEntity < List < Product >> getProducts () {
return ResponseEntity . ok ( productService . findAll ());
}
@ PreAuthorize ( "hasRole('ADMIN')" )
@ PostMapping ( "/api/products" )
public ResponseEntity < Product > createProduct (@ Valid @ RequestBody ProductRequest request) {
Product product = productService . create (request);
return ResponseEntity . status ( HttpStatus . CREATED ). body (product);
}