diff --git a/smarketing-java/ai-recommend/src/main/java/com/won/smarketing/recommend/config/SecurityConfig.java b/smarketing-java/ai-recommend/src/main/java/com/won/smarketing/recommend/config/SecurityConfig.java new file mode 100644 index 0000000..08a3949 --- /dev/null +++ b/smarketing-java/ai-recommend/src/main/java/com/won/smarketing/recommend/config/SecurityConfig.java @@ -0,0 +1,88 @@ +package com.won.smarketing.recommend.config; + +import com.won.smarketing.common.security.JwtAuthenticationFilter; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +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.config.http.SessionCreationPolicy; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.CorsConfigurationSource; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; + +import java.util.Arrays; + +/** + * Spring Security 설정 클래스 + * JWT 기반 인증 및 CORS 설정 + */ +@Configuration +@EnableWebSecurity +@RequiredArgsConstructor +public class SecurityConfig +{ + + private final JwtAuthenticationFilter jwtAuthenticationFilter; + + @Value("${allowed-origins}") + private String allowedOrigins; + /** + * Spring Security 필터 체인 설정 + * + * @param http HttpSecurity 객체 + * @return SecurityFilterChain + * @throws Exception 예외 + */ + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http + .csrf(AbstractHttpConfigurer::disable) + .cors(cors -> cors.configurationSource(corsConfigurationSource())) + .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + .authorizeHttpRequests(auth -> auth + .requestMatchers("/api/auth/**", "/api/member/register", "/api/member/check-duplicate/**", + "/api/member/validate-password", "/swagger-ui/**", "/v3/api-docs/**", + "/swagger-resources/**", "/webjars/**", "/actuator/**", "/health/**", "/error" + ).permitAll() + .anyRequest().authenticated() + ) + .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); + + return http.build(); + } + + /** + * 패스워드 인코더 빈 등록 + * + * @return BCryptPasswordEncoder + */ + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + + /** + * CORS 설정 + * + * @return CorsConfigurationSource + */ + @Bean + public CorsConfigurationSource corsConfigurationSource() { + CorsConfiguration configuration = new CorsConfiguration(); + configuration.setAllowedOrigins(Arrays.asList(allowedOrigins.split(","))); + configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS")); + configuration.setAllowedHeaders(Arrays.asList("*")); + configuration.setAllowCredentials(true); + + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", configuration); + return source; + } +} diff --git a/smarketing-java/ai-recommend/src/main/resources/application.yml b/smarketing-java/ai-recommend/src/main/resources/application.yml index d392c82..16fd541 100644 --- a/smarketing-java/ai-recommend/src/main/resources/application.yml +++ b/smarketing-java/ai-recommend/src/main/resources/application.yml @@ -70,4 +70,6 @@ info: app: name: ${APP_NAME:smarketing-recommend} version: "1.0.0-MVP" - description: "AI 마케팅 서비스 MVP - recommend" \ No newline at end of file + description: "AI 마케팅 서비스 MVP - recommend" + +allowed-origins: ${ALLOWED_ORIGINS:http://localhost:3000} \ No newline at end of file diff --git a/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/config/SecurityConfig.java b/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/config/SecurityConfig.java new file mode 100644 index 0000000..ca74fc1 --- /dev/null +++ b/smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/config/SecurityConfig.java @@ -0,0 +1,88 @@ +package com.won.smarketing.content.config; + +import com.won.smarketing.common.security.JwtAuthenticationFilter; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +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.config.http.SessionCreationPolicy; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.CorsConfigurationSource; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; + +import java.util.Arrays; + +/** + * Spring Security 설정 클래스 + * JWT 기반 인증 및 CORS 설정 + */ +@Configuration +@EnableWebSecurity +@RequiredArgsConstructor +public class SecurityConfig +{ + + private final JwtAuthenticationFilter jwtAuthenticationFilter; + + @Value("${allowed-origins}") + private String allowedOrigins; + /** + * Spring Security 필터 체인 설정 + * + * @param http HttpSecurity 객체 + * @return SecurityFilterChain + * @throws Exception 예외 + */ + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http + .csrf(AbstractHttpConfigurer::disable) + .cors(cors -> cors.configurationSource(corsConfigurationSource())) + .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + .authorizeHttpRequests(auth -> auth + .requestMatchers("/api/auth/**", "/api/member/register", "/api/member/check-duplicate/**", + "/api/member/validate-password", "/swagger-ui/**", "/v3/api-docs/**", + "/swagger-resources/**", "/webjars/**", "/actuator/**", "/health/**", "/error" + ).permitAll() + .anyRequest().authenticated() + ) + .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); + + return http.build(); + } + + /** + * 패스워드 인코더 빈 등록 + * + * @return BCryptPasswordEncoder + */ + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + + /** + * CORS 설정 + * + * @return CorsConfigurationSource + */ + @Bean + public CorsConfigurationSource corsConfigurationSource() { + CorsConfiguration configuration = new CorsConfiguration(); + configuration.setAllowedOrigins(Arrays.asList(allowedOrigins.split(","))); + configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS")); + configuration.setAllowedHeaders(Arrays.asList("*")); + configuration.setAllowCredentials(true); + + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", configuration); + return source; + } +} diff --git a/smarketing-java/marketing-content/src/main/resources/application.yml b/smarketing-java/marketing-content/src/main/resources/application.yml index 819d127..64a7bac 100644 --- a/smarketing-java/marketing-content/src/main/resources/application.yml +++ b/smarketing-java/marketing-content/src/main/resources/application.yml @@ -67,4 +67,7 @@ info: app: name: ${APP_NAME:smarketing-content} version: "1.0.0-MVP" - description: "AI 마케팅 서비스 MVP - content" \ No newline at end of file + description: "AI 마케팅 서비스 MVP - content" + + +allowed-origins: ${ALLOWED_ORIGINS:http://localhost:3000} \ No newline at end of file diff --git a/smarketing-java/member/src/main/java/com/won/smarketing/member/config/SecurityConfig.java b/smarketing-java/member/src/main/java/com/won/smarketing/member/config/SecurityConfig.java new file mode 100644 index 0000000..293caad --- /dev/null +++ b/smarketing-java/member/src/main/java/com/won/smarketing/member/config/SecurityConfig.java @@ -0,0 +1,88 @@ +package com.won.smarketing.member.config; + +import com.won.smarketing.common.security.JwtAuthenticationFilter; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +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.config.http.SessionCreationPolicy; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.CorsConfigurationSource; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; + +import java.util.Arrays; + +/** + * Spring Security 설정 클래스 + * JWT 기반 인증 및 CORS 설정 + */ +@Configuration +@EnableWebSecurity +@RequiredArgsConstructor +public class SecurityConfig +{ + + private final JwtAuthenticationFilter jwtAuthenticationFilter; + + @Value("${allowed-origins}") + private String allowedOrigins; + /** + * Spring Security 필터 체인 설정 + * + * @param http HttpSecurity 객체 + * @return SecurityFilterChain + * @throws Exception 예외 + */ + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http + .csrf(AbstractHttpConfigurer::disable) + .cors(cors -> cors.configurationSource(corsConfigurationSource())) + .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + .authorizeHttpRequests(auth -> auth + .requestMatchers("/api/auth/**", "/api/member/register", "/api/member/check-duplicate/**", + "/api/member/validate-password", "/swagger-ui/**", "/v3/api-docs/**", + "/swagger-resources/**", "/webjars/**", "/actuator/**", "/health/**", "/error" + ).permitAll() + .anyRequest().authenticated() + ) + .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); + + return http.build(); + } + + /** + * 패스워드 인코더 빈 등록 + * + * @return BCryptPasswordEncoder + */ + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + + /** + * CORS 설정 + * + * @return CorsConfigurationSource + */ + @Bean + public CorsConfigurationSource corsConfigurationSource() { + CorsConfiguration configuration = new CorsConfiguration(); + configuration.setAllowedOrigins(Arrays.asList(allowedOrigins.split(","))); + configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS")); + configuration.setAllowedHeaders(Arrays.asList("*")); + configuration.setAllowCredentials(true); + + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", configuration); + return source; + } +} diff --git a/smarketing-java/member/src/main/resources/application.yml b/smarketing-java/member/src/main/resources/application.yml index 92741bc..6306701 100644 --- a/smarketing-java/member/src/main/resources/application.yml +++ b/smarketing-java/member/src/main/resources/application.yml @@ -53,4 +53,6 @@ info: app: name: ${APP_NAME:smarketing-member} version: "1.0.0-MVP" - description: "AI 마케팅 서비스 MVP - member" \ No newline at end of file + description: "AI 마케팅 서비스 MVP - member" + +allowed-origins: ${ALLOWED_ORIGINS:http://localhost:3000} \ No newline at end of file diff --git a/smarketing-java/common/src/main/java/com/won/smarketing/common/config/SecurityConfig.java b/smarketing-java/store/src/main/java/com/won/smarketing/store/config/SecurityConfig.java similarity index 91% rename from smarketing-java/common/src/main/java/com/won/smarketing/common/config/SecurityConfig.java rename to smarketing-java/store/src/main/java/com/won/smarketing/store/config/SecurityConfig.java index dcc1f20..69fe47a 100644 --- a/smarketing-java/common/src/main/java/com/won/smarketing/common/config/SecurityConfig.java +++ b/smarketing-java/store/src/main/java/com/won/smarketing/store/config/SecurityConfig.java @@ -1,7 +1,8 @@ -package com.won.smarketing.common.config; +package com.won.smarketing.store.config; import com.won.smarketing.common.security.JwtAuthenticationFilter; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -25,10 +26,13 @@ import java.util.Arrays; @Configuration @EnableWebSecurity @RequiredArgsConstructor -public class SecurityConfig { +public class SecurityConfig +{ private final JwtAuthenticationFilter jwtAuthenticationFilter; + @Value("${allowed-origins}") + private String allowedOrigins; /** * Spring Security 필터 체인 설정 * @@ -72,7 +76,7 @@ public class SecurityConfig { @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); - configuration.setAllowedOriginPatterns(Arrays.asList("*")); + configuration.setAllowedOrigins(Arrays.asList(allowedOrigins.split(","))); configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS")); configuration.setAllowedHeaders(Arrays.asList("*")); configuration.setAllowCredentials(true); diff --git a/smarketing-java/store/src/main/resources/application.yml b/smarketing-java/store/src/main/resources/application.yml index 18a8934..42a2488 100644 --- a/smarketing-java/store/src/main/resources/application.yml +++ b/smarketing-java/store/src/main/resources/application.yml @@ -68,4 +68,6 @@ info: app: name: ${APP_NAME:smarketing-content} version: "1.0.0-MVP" - description: "AI 마케팅 서비스 MVP - content" \ No newline at end of file + description: "AI 마케팅 서비스 MVP - content" + +allowed-origins: ${ALLOWED_ORIGINS:http://localhost:3000} \ No newline at end of file