[Spring Security] Spring Security는 대체 언제 초기화되는 걸까? 자동 설정의 내부 동작 분석

심현민·2025년 9월 7일
0

Spring

목록 보기
12/18

이번 포스팅은 제가 Spring Security 배우면서 생긴 궁금증을 해소하기 위한 포스팅입니다.

"분명 나는 Security 관련 설정을 거의 한 게 없는데, 어떻게 서버를 띄우자마자 로그인 화면이 뜨고, 보안이 적용되는 거지?"

이 궁금증을 해결하기 위해 Spring Security의 자동 설정이 어떤 내부 동작 원리를 통해 이루어지는지 단계별로 분석해 보았습니다.

1. 기본 보안 설정의 적용

Spring Boot 프로젝트에 spring-boot-starter-security 의존성을 추가하고 애플리케이션을 실행하면, 별도의 설정 없이도 기본 로그인 페이지가 제공되는 것을 볼 수 있습니다.

또한, 모든 요청은 인증을 요구하며 콘솔에 출력되는 임시 비밀번호를 통해 로그인이 가능합니다.

저는 이 '자동'으로 처리되는 부분이 어떻게 동작하는지 명확히 이해할 필요가 있다고 생각했습니다.

2. 자동 설정 진입점

가장 먼저 살펴본 곳은 자동 설정 관련 클래스들이었습니다. Spring Boot의 자동 설정 핵심은 대부분 이곳에 있기 때문입니다.

디버거를 통해 코드를 따라가본 결과, SpringBootWebSecurityConfiguration 클래스에서 다음과 같은 코드를 발견했습니다.

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ SecurityFilterChain.class, HttpSecurity.class })
class SpringBootWebSecurityConfiguration {

    // ... (중략) ...

    @Configuration(proxyBeanMethods = false)
    @ConditionalOnMissingBean({ SecurityFilterChain.class })
    static class DefaultSecurityFilterChainConfiguration {
        @Bean
		@Order(SecurityProperties.BASIC_AUTH_ORDER)
		SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
			http.authorizeHttpRequests((requests) -> requests.anyRequest().authenticated());
			http.formLogin(withDefaults());
			http.httpBasic(withDefaults());
			return http.build();
		}
    }
}

이 코드가 바로 '자동 보안 설정'의 핵심입니다.

이제 이 코드가 어떤 조건 하에 실행되는지 @ConditionalOn... 어노테이션을 통해 확인해 보았습니다.

조건 1. 빈(Bean) 등록 여부

@ConditionalOnClass({ SecurityFilterChain.class, HttpSecurity.class })

이 조건은 클래스패스에 SecurityFilterChainHttpSecurity 클래스가 존재해야 함을 의미합니다. Spring Security 의존성을 추가했다면 당연히 충족되는 조건입니다.

@ConditionalOnMissingBean({ SecurityFilterChain.class })
이것이 핵심 조건이었습니다. 스프링 컨테이너에 개발자가 직접 정의한 SecurityFilterChain 타입의 빈(Bean)이 존재하지 않을 경우에만 이 설정을 사용한다는 의미입니다.

즉, 우리가 흔히 작성하는 SecurityConfig와 같은 설정 클래스에서 SecurityFilterChain을 빈으로 등록하면, 이 기본 설정은 동작하지 않게 됩니다. 반대로, 별도의 설정을 하지 않으면 Spring Boot가 기본 보안 설정을 자동으로 구성해주는 것입니다.

3. 초기화 흐름

디버깅을 통해 파악한 Spring Security의 전체적인 초기화 흐름은 다음과 같습니다.

  1. 사용자 정보 설정 (UserDetailsServiceAutoConfiguration)

    • 인증에 사용할 기본 사용자 정보를 설정합니다. SecurityProperties 클래스를 통해 user라는 이름의 사용자와 랜덤 비밀번호를 생성하여 메모리에 등록합니다. 이것이 콘솔에서 확인 가능한 임시 계정입니다.
  2. 보안 필터 체인 구성 (SpringBootWebSecurityConfiguration)

    • 위에서 분석한 defaultSecurityFilterChain 빈을 생성합니다.
    • 이 과정에서 "모든 요청은 인증(authenticated) 필요", "폼 로그인(formLogin) 방식 사용", "HTTP Basic 인증(httpBasic) 사용"이라는 핵심 보안 규칙이 정의됩니다.
  3. 필터 체인 적용 및 작동

    • 생성된 필터 체인이 서블릿 필터에 등록되어, 이후 들어오는 모든 HTTP 요청에 대해 정의된 보안 규칙을 적용하기 시작합니다.

결론적으로 Spring Security는 '기본 사용자 준비 → 기본 보안 규칙 설정 → 필터에 적용' 이라는 명확한 단계를 거쳐 초기화되고 있었습니다.

4. 자동 설정의 동작 원리 이해

이번 분석을 통해 막연하게 느껴졌던 Spring Security의 자동 설정이 @Conditional 어노테이션을 기반으로 한 명확한 조건에 따라 동작한다는 것을 확인했습니다.

  • 모든 요청에 인증이 필요했던 이유: anyRequest().authenticated() 설정 때문
  • 로그인 폼이 나타났던 이유: formLogin(withDefaults()) 설정 때문
  • 임시 계정이 존재했던 이유: UserDetailsServiceAutoConfiguration이 기본 사용자를 생성해주기 때문

이제 의존성 추가만으로 보안 기능이 활성화되는 원리를 이해할 수 있습니다.

이를 바탕으로 필요에 따라 SecurityFilterChain 빈을 등록하여 기본 동작을 재정의하고 원하는 보안 설정을 커스터마이징할 수 있게 되는 것입니다.

다음 포스팅에서는 이 기본 설정을 비활성화하고, 직접 SecurityConfig를 작성하는 과정을 다뤄보겠습니다.

profile
혼자 성장하는 것보다 함께 성장하는 것을 선호합니다.

0개의 댓글