diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index a773736..d4f9757 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -231,7 +231,7 @@ jobs: key: ${{ secrets.EC2_KEY }} script: | set -e - for i in {1..10}; do + for i in {1..20}; do echo "[$i] health check..." if curl -f http://localhost:${{ env.STOPPED_PORT }}/actuator/health > /dev/null 2>&1; then echo "health check success" diff --git a/src/main/java/net/studioxai/studioxBe/domain/auth/service/OauthService.java b/src/main/java/net/studioxai/studioxBe/domain/auth/service/OauthService.java index c7329c0..097ce9a 100644 --- a/src/main/java/net/studioxai/studioxBe/domain/auth/service/OauthService.java +++ b/src/main/java/net/studioxai/studioxBe/domain/auth/service/OauthService.java @@ -14,7 +14,9 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.util.UriUtils; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Map; import java.util.UUID; @@ -38,16 +40,19 @@ public String getGoogleLoginUrl(String redirectUrl) { return googleOauth.getOauthRedirectURL(redirectUrl); } - public GoogleCallbackDto loginWithGoogle(String code, String redirectUrl) { + public GoogleCallbackDto loginWithGoogle(String code, String state) { validateCode(code); - validateRedirectUrl(redirectUrl); + + String decodedRedirectUrl = UriUtils.decode(state, StandardCharsets.UTF_8); + + validateRedirectUrl(decodedRedirectUrl); GoogleUserInfoResponse userInfo = getGoogleUserInfo(code); User user = findOrCreateGoogleUser(userInfo); Map tokens = authService.issueTokens(user.getId()); - return GoogleCallbackDto.create(redirectUrl, tokens.get("accessToken"), tokens.get("refreshToken")); + return GoogleCallbackDto.create(decodedRedirectUrl, tokens.get("accessToken"), tokens.get("refreshToken")); } private void validateCode(String code) { diff --git a/src/main/java/net/studioxai/studioxBe/global/config/SecurityConfig.java b/src/main/java/net/studioxai/studioxBe/global/config/SecurityConfig.java index b80c5e3..e8e0049 100644 --- a/src/main/java/net/studioxai/studioxBe/global/config/SecurityConfig.java +++ b/src/main/java/net/studioxai/studioxBe/global/config/SecurityConfig.java @@ -6,6 +6,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; @@ -25,6 +26,8 @@ import java.util.Arrays; +import static org.springframework.security.config.Customizer.withDefaults; + @Configuration @EnableWebSecurity @RequiredArgsConstructor @@ -73,12 +76,13 @@ public PasswordEncoder passwordEncoder() { }; @Bean - public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + @Order(1) + public SecurityFilterChain swaggerFilterChain(HttpSecurity http) throws Exception { http + .securityMatcher(SwaggerPatterns) .cors(c -> c.configurationSource(corsConfigurationSource())) .csrf(AbstractHttpConfigurer::disable) - .httpBasic(AbstractHttpConfigurer::disable) - .formLogin(AbstractHttpConfigurer::disable); + .httpBasic(withDefaults()); http.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS) @@ -86,25 +90,33 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti if (environmentUtil.isProdProfile()) { http - .authorizeHttpRequests(auth -> auth - .requestMatchers(SwaggerPatterns).authenticated() - ) - .httpBasic(basic -> {}); - } - else { + .authorizeHttpRequests(auth -> auth.anyRequest().authenticated()) + .httpBasic(withDefaults()); + } else { http - .authorizeHttpRequests(auth -> auth - .requestMatchers(SwaggerPatterns).permitAll() - ); + .authorizeHttpRequests(auth -> auth.anyRequest().permitAll()); } + return http.build(); + } + + @Bean + @Order(2) + public SecurityFilterChain apiFilterChain(HttpSecurity http) throws Exception { http - .authorizeHttpRequests(auth -> auth - .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() - .requestMatchers(PermitAllPatterns).permitAll() - .requestMatchers(HttpMethod.GET, GetPermitPatterns).permitAll() - .anyRequest().authenticated() - ); + .securityMatcher("/api/**") + .csrf(AbstractHttpConfigurer::disable) + .httpBasic(AbstractHttpConfigurer::disable) + .formLogin(AbstractHttpConfigurer::disable) + .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + .cors(c -> c.configurationSource(corsConfigurationSource())); + + http.authorizeHttpRequests(auth -> auth + .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() + .requestMatchers(HttpMethod.GET, GetPermitPatterns).permitAll() + .requestMatchers(PermitAllPatterns).permitAll() + .anyRequest().authenticated() + ); http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); @@ -136,4 +148,4 @@ public CorsConfigurationSource corsConfigurationSource() { } -} +} \ No newline at end of file