From cd37bbe7d1d473a2b7c5db1888cf0e71481d0120 Mon Sep 17 00:00:00 2001 From: forge-bot Date: Mon, 13 Jul 2026 10:30:31 +0000 Subject: [PATCH] =?UTF-8?q?=EC=9D=B8=EC=A6=9D/=EA=B6=8C=ED=95=9C=20?= =?UTF-8?q?=EC=97=85=EB=AC=B4=20=EA=B7=9C=EC=B9=99=EA=B3=BC=20=EC=A0=84?= =?UTF-8?q?=ED=99=98=20=EB=B6=88=EB=B3=80=EC=8B=9D=20=EC=B6=94=EC=B6=9C=20?= =?UTF-8?q?(codex-bais-final3-20260713-192718-BAIS-SPRING-ANA-AUTH-001)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/auth/config/SecurityConfig.java | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 auth-migration/src/main/java/com/example/auth/config/SecurityConfig.java diff --git a/auth-migration/src/main/java/com/example/auth/config/SecurityConfig.java b/auth-migration/src/main/java/com/example/auth/config/SecurityConfig.java new file mode 100644 index 0000000..9e3c234 --- /dev/null +++ b/auth-migration/src/main/java/com/example/auth/config/SecurityConfig.java @@ -0,0 +1,76 @@ +package com.example.auth.config; + +import com.example.auth.security.*; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +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.security.web.csrf.CookieCsrfTokenRepository; +import org.springframework.security.web.csrf.CsrfTokenRequestAttributeHandler; + +/** + * Security Configuration - preserves all AUTH-0XX invariants. + * AUTH-004: BCrypt cost factor 12 + * AUTH-050/051: Public vs authenticated endpoints + * AUTH-052/053/054: Role-based access control + */ +@Configuration +@EnableWebSecurity +@EnableMethodSecurity(prePostEnabled = true) +public class SecurityConfig { + + private final JwtAuthenticationFilter jwtAuthenticationFilter; + private final CustomAuthenticationEntryPoint authenticationEntryPoint; + private final CustomAccessDeniedHandler accessDeniedHandler; + + public SecurityConfig( + JwtAuthenticationFilter jwtAuthenticationFilter, + CustomAuthenticationEntryPoint authenticationEntryPoint, + CustomAccessDeniedHandler accessDeniedHandler) { + this.jwtAuthenticationFilter = jwtAuthenticationFilter; + this.authenticationEntryPoint = authenticationEntryPoint; + this.accessDeniedHandler = accessDeniedHandler; + } + + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + CsrfTokenRequestAttributeHandler requestHandler = new CsrfTokenRequestAttributeHandler(); + requestHandler.setCsrfRequestAttributeName("_csrf"); + + http + .csrf(csrf -> csrf + .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) + .csrfTokenRequestHandler(requestHandler) + .ignoringRequestMatchers("/auth/login", "/auth/refresh") + ) + .sessionManagement(session -> session + .sessionCreationPolicy(SessionCreationPolicy.STATELESS) + .sessionFixation().migrateSession() + ) + .authorizeHttpRequests(auth -> auth + .requestMatchers("/auth/login", "/auth/refresh").permitAll() + .requestMatchers("/admin/**").hasRole("ADMIN") + .requestMatchers("/users/**").hasAnyRole("MANAGER", "ADMIN") + .requestMatchers("/reports/**").authenticated() + .anyRequest().authenticated() + ) + .exceptionHandling(ex -> ex + .authenticationEntryPoint(authenticationEntryPoint) + .accessDeniedHandler(accessDeniedHandler) + ) + .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); + + return http.build(); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(12); // AUTH-004 + } +}