@RefreshScope 트러블 슈팅

위성구·2024년 9월 29일

config client를 의존성을 추가 하면
@RefreshScope를 사용할 수 있다.
이 어노테이션은 컨피그 서버에 설정을 업데이트를 하면 각 마이크로 서비스에서 새로운 설정을 빈에 반영하기 위해서 사용한다.

그래서 난 이걸 보안에 테스트를 해보았다.

문제 발견

@Configuration
@EnableWebSecurity
@RefreshScope
@ConditionalOnProperty(name = "common.bean.security.enabled", havingValue = "true", matchIfMissing = false)
public class SecurityConfig {
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    @Bean
    SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
        http.csrf(AbstractHttpConfigurer::disable);
        http.formLogin(AbstractHttpConfigurer::disable);
        http.httpBasic(AbstractHttpConfigurer::disable);
        http.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
        // Auth Server 를 제외한 다른 모듈을요청 접근 설정
        http.authorizeHttpRequests((auth) -> auth
                // TODO : 각 마이크로 서비스 인가 설정
                .anyRequest().permitAll()
        );
        // 권한이 없는 사용자가 접근할 때의 처리
        http.exceptionHandling(handler -> handler
                .accessDeniedHandler((request, response, accessDeniedException) -> {
                    response.setContentType("application/json;charset=UTF-8");
                    response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                    response.getWriter().write("{\"error\": \"사용자의 권한으로는 접근이 불가합니다.\"}");
                }));
        return http.build();
    }
}

시큐리티 빈에 적용을 했는데 서버를 실행하니 이 필터를 사용한다는 yml파일에 설정을 했음에도 시큐리티가 제공하는 기본 필터가 적용 되었다.

원인

@RefreshScope를 Spring Security 필터 빈 클래스에 적용할 경우 발생할 수 있는 주요 문제점은 Spring Security의 필터 체인과 @RefreshScope의 동작 방식 간의 타이밍 불일치 때문이다.

  1. 필터 체인 초기화 시점 문제
    Spring Security 필터 체인은 애플리케이션이 시작될 때 한 번 초기화되고, 그 이후로는 보통 변경되지 않습니다. 필터 체인은 애플리케이션의 보안 설정에 따라 고정된 순서로 요청을 처리합니다.
    @RefreshScope는 Spring Cloud Config와 함께 사용되어, 컨피그 서버에서 설정이 변경되면 빈을 다시 로드(리프레시)하여 설정값을 동적으로 적용할 수 있게 해줍니다. 하지만 이 리프레시 동작이 일어날 때, Spring Security의 필터 빈이 다시 초기화되면서 보안 필터 체인이 깨지거나 예기치 않은 동작을 일으킬 수 있습니다.
  • 예를 들어, @RefreshScope가 적용된 필터가 다시 로드되면, Security 필터 체인은 정상적으로 작동하지 않을 수 있으며, 이는 기존 필터 체인이 불완전하게 재구성되는 문제를 야기할 수 있습니다.
  1. 필터 빈의 상태 관리 문제
    Spring Security 필터 빈은 상태를 관리하지 않으며, 단순히 HTTP 요청을 처리하는 동안 작동합니다. @RefreshScope는 빈의 상태를 다시 로드하면서 새로 만들어진 필터 빈을 반환합니다. 이로 인해 보안 관련 상태가 일관성 없이 리셋될 수 있으며, 필터 체인이 의도대로 작동하지 않게 됩니다.

예를 들어, 필터 빈이 다시 로드되면 기존의 세션 관리나 인증 상태가 불완전하게 처리되거나, 적용되지 않을 가능성이 있습니다.

  1. 필터 체인 순서 문제
    Spring Security의 필터 체인은 특정 순서로 동작하며, 각 필터는 요청을 특정 순서로 가로채서 처리합니다. 그러나 @RefreshScope가 적용된 필터 빈이 리프레시되면 필터 체인의 순서가 변경되거나, 필터가 제대로 재등록되지 않아 인증 및 인가 로직이 정상적으로 처리되지 않을 수 있습니다.

  2. 비즈니스 로직의 예측 불가능성
    Spring Security는 애플리케이션의 중요한 보안 계층입니다. @RefreshScope를 통해 빈이 동적으로 재생성되면 예기치 않은 순간에 보안 로직이 무효화될 수 있으며, 이는 보안 취약점을 초래할 수 있습니다. 예를 들어, 보안 설정이 다시 로드되는 동안 적절한 인증 및 인가 검증이 이루어지지 않으면 보안 구멍이 발생할 수 있습니다.

결론

@RefreshScope는 비보안성 빈에서만 사용하는 것이 더 안전합니다.
예를 들어 토큰의 유효시간

또한 DB연결 설정을 변경하고 /actuator/busrefresh을 해도 적용이 되지않으며 서버가 재시작해야 적용된다.

profile
안녕하세요.

0개의 댓글