초기화 과정 이해
Spring Security의 자동 설정과 필터 체인 초기화 구조
목차
1. 프로젝트 생성 및 자동 설정
개념
Spring Boot 3.x 기반 프로젝트에 spring-boot-starter-security 의존성을 추가하면 별도의 설정 코드 없이도 기본적인 웹 보안 기능이 자동으로 활성화된다. 자동 설정에 의해 다음과 같은 기본 보안 정책이 적용된다.
- 모든 요청에 대해 인증 여부를 검증하며 인증이 승인되어야 자원에 접근할 수 있다
- 인증 방식은 폼 로그인과 httpBasic 로그인을 제공한다
- 로그인 페이지가 자동으로 생성되어 렌더링된다
- 기본 계정 한 개가 제공된다 (username:
user, password: 콘솔에 출력되는 랜덤 문자열)
이 기본 설정은 SpringBootWebSecurityConfiguration 클래스에 의해 생성된다.
핵심 코드
// SpringBootWebSecurityConfiguration 자동 설정 클래스 @Bean @Order(SecurityProperties.BASIC_AUTH_ORDER) SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) { http.authorizeRequests().anyRequest().authenticated(); http.formLogin(); http.httpBasic(); return http.build(); }
// build.gradle 의존성 구성 dependencies { implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.security:spring-security-test' }
SpringBootWebSecurityConfiguration#defaultSecurityFilterChain확인할 변수:
http 객체 내부의 설정 클래스 목록, 생성되는 필터 체인
2. SecurityBuilder / SecurityConfigurer
개념
SecurityBuilder는 빌더 클래스로서 웹 보안을 구성하는 빈 객체와 설정 클래스들을 생성하는 역할을 한다. 대표적인 구현체로 HttpSecurity, WebSecurity, AuthenticationManagerBuilder가 있다.
SecurityConfigurer는 HTTP 요청과 관련된 보안 처리를 담당하는 필터들을 생성하고 여러 초기화 설정에 관여한다. 대표적인 구현체로는 SecurityContextConfigurer, HttpBasicConfigurer, FormLoginConfigurer, CsrfConfigurer, ExceptionHandlingConfigurer, AnonymousConfigurer 등이 있다.
SecurityBuilder는 SecurityConfigurer를 참조하고 있으며, 인증 및 인가 초기화 작업은 SecurityConfigurer에 의해 진행된다.
동작 흐름
SecurityConfigurer → Filter 매핑
AbstractConfiguredSecurityBuilder#doBuild()확인할 변수:
configurers 맵 — 등록된 SecurityConfigurer 목록과 각 Configurer가 생성하는 필터
3. HttpSecurity / WebSecurity
HttpSecurity
HttpSecurityConfiguration에서 HttpSecurity를 생성하고 초기화를 진행한다. HttpSecurity는 보안에 필요한 각 설정 클래스와 필터들을 생성하고 최종적으로 SecurityFilterChain 빈을 생성한다.
WebSecurity
WebSecurityConfiguration에서 WebSecurity를 생성하고 초기화를 진행한다. HttpSecurity에서 생성한 SecurityFilterChain 빈을 SecurityBuilder에 저장한다. WebSecurity가 build()를 실행하면 SecurityFilterChain을 꺼내어 FilterChainProxy 생성자에게 전달한다.
전체 빌드 흐름
SecurityFilterChain 인터페이스
SecurityFilterChain은 두 가지 핵심 메서드를 가진 인터페이스다.
boolean matches(HttpServletRequest request)— 현재 요청이 이 필터 체인에 의해 처리되어야 하는지 여부를 결정한다List<Filter> getFilters()— 현재 필터 체인에 포함된 Filter 객체의 리스트를 반환한다
기본 필터 목록
HttpSecurity의 기본 설정으로 생성되는 필터 체인:
| 순서 | 필터 |
|---|---|
| 0 | DisableEncodeUrlFilter |
| 1 | WebAsyncManagerIntegrationFilter |
| 2 | SecurityContextHolderFilter |
| 3 | HeaderWriterFilter |
| 4 | CorsFilter |
| 5 | CsrfFilter |
| 6 | LogoutFilter |
| 7 | UsernamePasswordAuthenticationFilter |
| 8 | DefaultLoginPageGeneratingFilter |
| 9 | DefaultLogoutPageGeneratingFilter |
| 10 | BasicAuthenticationFilter |
| 11 | RequestCacheAwareFilter |
| 12 | SecurityContextHolderAwareRequestFilter |
| 13 | AnonymousAuthenticationFilter |
| 14 | ExceptionTranslationFilter |
| 15 | AuthorizationFilter |
HttpSecurity#build() — DefaultSecurityFilterChain 생성 시점확인할 변수:
result 객체의 requestMatcher와 filters (size = 12~16)📍 브레이크포인트:
WebSecurity#performBuild() — FilterChainProxy 생성 시점확인할 변수:
filterChainProxy의 filterChains 리스트와 내부 필터 목록
4. DelegatingFilterProxy / FilterChainProxy
서블릿 필터 (Filter)
서블릿 필터는 웹 애플리케이션에서 클라이언트의 요청과 서버의 응답을 가공하거나 검사하는 구성 요소다. 서블릿 컨테이너(WAS)에서 생성되고 실행되며, 요청이 서블릿에 도달하기 전이나 응답이 클라이언트에게 전달되기 전에 특정 작업을 수행할 수 있다.
public class ExampleFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // 필터 초기화 시 필요한 작업 수행 } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // pre-processing: 요청 처리 전 작업 chain.doFilter(request, response); // 다음 필터로 전달 // post-processing: 응답 처리 후 작업 } @Override public void destroy() { // 필터가 제거될 때 정리 작업 수행 } }
DelegatingFilterProxy
스프링에서 사용되는 특별한 서블릿 필터로, 서블릿 컨테이너와 스프링 애플리케이션 컨텍스트 간의 연결고리 역할을 한다. "springSecurityFilterChain" 이름으로 생성된 빈을 ApplicationContext에서 찾아 요청을 위임하며, 실제 보안 처리를 수행하지는 않는다.
FilterChainProxy
"springSecurityFilterChain" 이름으로 생성되는 필터 빈으로서, DelegatingFilterProxy로부터 요청을 위임 받아 실제 보안 처리를 수행한다. 내부적으로 하나 이상의 SecurityFilterChain 객체들을 가지고 있으며 요청 URL 정보를 기준으로 적절한 SecurityFilterChain을 선택하여 필터들을 호출한다.
전체 위임 구조
DelegatingFilterProxy → FilterChainProxy 위임 구조
요청 위임"| FCP subgraph SPRING["Spring IoC Container"] direction TB FCP["FilterChainProxy"]:::fcp subgraph SFC["SecurityFilterChain"] direction TB SF0["AuthenticationFilter"]:::sec_f SF1["..."]:::sec_f SF2["AuthorizationFilter"]:::sec_f SF0 --> SF1 --> SF2 end FCP --> SFC end classDef servlet_f fill:#2d333b,stroke:#768390,color:#e6edf3 classDef dfp fill:#1c3a5f,stroke:#58a6ff,color:#ffffff,font-weight:bold classDef fcp fill:#3d1f5c,stroke:#bc8cff,color:#ffffff,font-weight:bold classDef sec_f fill:#1a3a2a,stroke:#3fb950,color:#e6edf3
FilterChainProxy의 필터 순차 실행
FilterChainProxy는 0번째 필터부터 마지막 필터까지 위에서 순서대로 호출하면서 요청을 처리한다. 마지막 인가 처리를 하는 필터(AuthorizationFilter)까지 특별한 예외나 오류가 발생하지 않으면 성공적으로 요청이 서블릿으로 넘어가게 된다.
DelegatingFilterProxy#doFilter() — 위임 시점확인할 변수:
delegate — 실제 위임 대상 FilterChainProxy 객체📍 브레이크포인트:
FilterChainProxy$VirtualFilterChain#doFilter() — 필터 순차 실행확인할 변수:
additionalFilters (size=16), currentPosition (0→15 증가)
5. 사용자 정의 보안 설정하기
개념
기본 자동 설정 대신 사용자 정의 보안 설정을 구성하려면 SecurityFilterChain 타입의 빈을 직접 정의한다. 사용자 정의 SecurityFilterChain 빈을 등록하면 자동 설정에 의한 SecurityFilterChain 빈은 생성되지 않는다.
사용자 정의 보안 기능 구현
@EnableWebSecurity"]:::config --> SFC["SecurityFilterChain
빈으로 정의"]:::chain SFC --> HS["HttpSecurity
의존 주입"]:::builder HS --> AUTH_API HS --> AUTHZ_API subgraph AUTH_API["인증 API"] direction TB A1["http.formLogin()"]:::api A2["http.logout()"]:::api A3["http.csrf()"]:::api A4["http.httpBasic()"]:::api A5["http.sessionManagement()"]:::api A6["http.rememberMe()"]:::api A7["http.exceptionHandling()"]:::api A8["http.addFilter()"]:::api end subgraph AUTHZ_API["인가 API"] direction TB B1["http.authorizeHttpRequests()"]:::api B2[".requestMatchers('/admin')"]:::api B3[".hasRole('USER')"]:::api B4[".permitAll()"]:::api B5[".authenticated()"]:::api B6[".denyAll()"]:::api end classDef config fill:#3d1f5c,stroke:#bc8cff,color:#ffffff,font-weight:bold classDef chain fill:#1a3a2a,stroke:#3fb950,color:#ffffff classDef builder fill:#1c3a5f,stroke:#58a6ff,color:#ffffff classDef api fill:#2d333b,stroke:#768390,color:#e6edf3
기본 구현 코드
@EnableWebSecurity @Configuration public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests(auth -> auth.anyRequest().authenticated()) .formLogin(Customizer.withDefaults()); return http.build(); } }
SecurityFilterChain을 빈으로 정의하게 되면 자동설정에 의한 SecurityFilterChain 빈은 생성되지 않는다.
사용자 추가 설정
application.yml 파일에 사용자를 설정할 수 있다.
spring: security: user: name: user password: 1111 roles: USER
또는 자바 설정 클래스에서 InMemoryUserDetailsManager를 직접 정의할 수도 있다.
@Bean public InMemoryUserDetailsManager inMemoryUserDetailsManager() { UserDetails user = User.withUsername("user") .password("{noop}1111") .authorities("ROLE_USER") .build(); return new InMemoryUserDetailsManager(user); }
정리
- spring-boot-starter-security 의존성만으로 기본 보안 설정이 자동 적용된다
- SecurityBuilder는 보안 객체를 생성하는 빌더이며, SecurityConfigurer가 실제 초기화 작업을 수행한다
- HttpSecurity는 각 SecurityConfigurer를 통해 필터들을 생성하고 SecurityFilterChain을 만든다
- WebSecurity는 SecurityFilterChain을 모아 FilterChainProxy를 생성한다
- DelegatingFilterProxy는 서블릿 컨테이너와 스프링 컨텍스트 사이의 브릿지 역할을 하며, 실제 보안 처리는 FilterChainProxy에 위임된다
- 사용자 정의 SecurityFilterChain 빈을 등록하면 자동 설정 빈을 대체하여 세부적인 보안 정책을 구성할 수 있다
'Java & Spring > Spring Security' 카테고리의 다른 글
| 06. 예외 처리 (0) | 2026.08.05 |
|---|---|
| 05. 세션 관리 (0) | 2026.08.05 |
| 04. 인증 상태 영속성 (0) | 2026.08.04 |
| 03. 인증 아키텍처 (0) | 2026.08.04 |
| 02. 인증 프로세스 (0) | 2026.08.01 |