From bcb97312cd4df04a9b05efdad6a9a358ae941ae5 Mon Sep 17 00:00:00 2001 From: Pablo de la Torre Jamardo Date: Fri, 19 Sep 2025 17:09:09 +0200 Subject: [PATCH] fix(cors): allow origins from environment variable --- .env.example | 1 + bootstrap/src/main/resources/application.yml | 2 ++ docker-compose.yml | 1 + infrastructure/pom.xml | 5 +++ .../infrastructure/config/CorsConfig.java | 35 +++++++++++++++++++ .../infrastructure/config/SecurityConfig.java | 31 ++++++++++++++++ 6 files changed, 75 insertions(+) create mode 100644 infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/config/CorsConfig.java create mode 100644 infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/config/SecurityConfig.java diff --git a/.env.example b/.env.example index e781ca2..627cf7a 100644 --- a/.env.example +++ b/.env.example @@ -1,6 +1,7 @@ SPRING_PROFILES_ACTIVE=dev APP_ENCRYPTION_SECRET=123456789 +APP_ALLOWED_ORIGINS=http://localhost:8080 DB_NAME=EXAMPLE_DB DB_USER=EXAMPLE diff --git a/bootstrap/src/main/resources/application.yml b/bootstrap/src/main/resources/application.yml index 6a748b3..444e066 100644 --- a/bootstrap/src/main/resources/application.yml +++ b/bootstrap/src/main/resources/application.yml @@ -5,6 +5,8 @@ info: app: encryption: secret: ${APP_ENCRYPTION_SECRET} + cors: + allowed-origins: ${APP_ALLOWED_ORIGINS:http://localhost:8080} server: port: 8080 diff --git a/docker-compose.yml b/docker-compose.yml index 0d8a202..0d3f46e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -14,6 +14,7 @@ services: DB_USER: ${DB_USER} DB_PASSWORD: ${DB_PASSWORD} APP_ENCRYPTION_SECRET: ${APP_ENCRYPTION_SECRET} + APP_ALLOWED_ORIGINS: ${APP_ALLOWED_ORIGINS} GMAIL_OAUTH_CLIENT_ID: ${GMAIL_OAUTH_CLIENT_ID} GMAIL_OAUTH_CLIENT_SECRET: ${GMAIL_OAUTH_CLIENT_SECRET} networks: diff --git a/infrastructure/pom.xml b/infrastructure/pom.xml index adef519..fdbd5bd 100644 --- a/infrastructure/pom.xml +++ b/infrastructure/pom.xml @@ -49,6 +49,11 @@ spring-boot-starter-validation + + org.springframework.boot + spring-boot-starter-security + + org.reflections reflections diff --git a/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/config/CorsConfig.java b/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/config/CorsConfig.java new file mode 100644 index 0000000..0b3b0b5 --- /dev/null +++ b/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/config/CorsConfig.java @@ -0,0 +1,35 @@ +package com.pablotj.restemailbridge.infrastructure.config; + +import java.util.Arrays; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.CorsConfigurationSource; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; + +import java.util.List; + +@Configuration +public class CorsConfig { + + @Value("${app.cors.allowed-origins}") + private String allowedOriginsString; + + @Bean + public CorsConfigurationSource corsConfigurationSource() { + CorsConfiguration config = new CorsConfiguration(); + + List allowedOrigins = Arrays.asList(allowedOriginsString.split(",")); + config.setAllowedOriginPatterns(allowedOrigins); + + config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS")); + config.setAllowedHeaders(List.of("*")); + config.setAllowCredentials(true); + + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", config); + + return source; + } +} diff --git a/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/config/SecurityConfig.java b/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/config/SecurityConfig.java new file mode 100644 index 0000000..95b9cc5 --- /dev/null +++ b/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/config/SecurityConfig.java @@ -0,0 +1,31 @@ +package com.pablotj.restemailbridge.infrastructure.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.web.cors.CorsConfigurationSource; + +@Configuration +@EnableWebSecurity +public class SecurityConfig { + + private final CorsConfigurationSource corsConfigurationSource; + + public SecurityConfig(CorsConfigurationSource corsConfigurationSource) { + this.corsConfigurationSource = corsConfigurationSource; + } + + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http + .csrf(AbstractHttpConfigurer::disable) + .cors(cors -> cors.configurationSource(corsConfigurationSource)) + .authorizeHttpRequests(auth -> auth + .anyRequest().permitAll() + ); + return http.build(); + } +}