spring-security

[Spring Security] 핵심 클래스 구조 SpringBuilder, SpringConfigurer

에그마요샌드위츼 2025. 5. 2. 23:17

0. 들어가며

Spring Security는 애플리케이션의 보안을 책임지는 강력한 프레임워크이다
서버가 실행될 때, Spring Security는 인증(Authentication)과 인가(Authorization)에 관련된 여러 작업을 자동으로 초기화해준다.
이 과정을 해주는 핵심 클래스가 두 가지 있는데

  • 🔨 SecurityBuilder
  • ⚙️ SecurityConfigurer

1) 인증이란?

  • 사용자가 시스템에 로그인할  권한이 있는지 확인하는 절차이다.
  • 아이디와 비밀번호를 제출하면, 그 정보가 등록된 사용자 정보와 일치하는지 검사한다.
  • 인증이 성공하면 `Authentication` 객체가 생성되고` SecurityContext`에 저장된다.
  • Spring Security에서는 `AuthenticationManager`가 이 인증 절차를 담당한다.

 

2) 인가란?

  • 인증된 사용자가 특정 자원에 접근할 권한이 있는가를 확인하는 절차이다.
  • 로그인은 되었지만, 관리자 전용 페이지에 들어갈 수 있는지 확인하는 것이다
  • Spring Security에서는 다음과 같이 설정한다: 
.authorizeHttpRequests()
  .requestMatchers("/admin/**").hasRole("ADMIN")
  .anyRequest().authenticated();

3) 스프링 시큐리티는 필터 기반 보안 프레임워크

모든 요청은 여러 개의 보안 필터를 통해 처리되고 그만큼 필터의 생성 및 설정은 핵심 작업이며 이는 다음 두가지 클래스에 의해 관리된다.


1. SecurityBuilder 란

 

  • 인증/인가 관련된 필터, 설정, 보안 객체들을 만들어내는 빌더 메서드
  • 대표적인 구현체: `HttpSecurity`, `WebSecurity`
public interface SecurityBuilder<O> {
    O build() throws Exception;
}

2. SecurityConfigurer란?

SecurityBuilder에 보안 설정을 주입해주는 설정 도우미

 

  • Builder에 설정을 추가해주는 역할, 말하자면 HttpSecurity에 옵션을 붙이는 플러그인 같은 존재이다
  • 주요 메서드: 
    • `init(B builder)` : 초기 준비 (기본 값, 의존성 연결 등)
    • `configure(B builder) ` : 실제 설정 적용 (필터 등록 등)
public interface SecurityConfigurer<O, B extends SecurityBuilder<O>> {
    void init(B builder) throws Exception; // 초기화 작업
    void configure(B builder) throws Exception; // 실제 설정 적용
}

 

실제 사용하는 예

  • .formLogin() → FormLoginConfigurer
  • .csrf() → CsrfConfigurer
  • .sessionManagement() → SessionManagementConfigurer

`SecurityBuilder`는 `SecurityConfiguer`을 참조하고 있고(사용하고 있고) 인증 인가는 후자에 의해 진행된다.

`SecurityConfiguer` 는 Http 요청과 관련된 보안 처리를 담당하는 필터들을 생성하고 여러 초기화 작업을 하게되는데

누구에 의해 하게 되냐 -> `SecurityBuilder` 에 의해서 하게된다

 

 

 

3. HttpSecurity 초기화 시 자동으로 적용되는 설정들( 초기화 흐름 ) 

🧱  HttpSecurity는 웹 보안 설정을 담당하는 핵심 클래스 ( SpringBuilder의 구현체 )

인증/인가 외에도 세션, 예외 처리, 익명 사용자, 헤더 설정 등 웹 보안에 필요한 기능들이 자동으로 연결되는 구조

 

⚙️ 초기화 시 자동 등록되는 설정들 ( 각 설정은 내부적으로 SecurityConfigurer 구현체 )

http
  .csrf(withDefaults())                        // CSRF 보호
  .addFilter(webAsyncManagerIntegrationFilter) // 비동기 처리 지원
  .exceptionHandling(withDefaults())           // 예외 처리
  .headers(withDefaults())                     // 보안 헤더
  .sessionManagement(withDefaults())           // 세션 관리
  .securityContext(withDefaults())             // 보안 컨텍스트 저장
  .requestCache(withDefaults())                // 요청 캐시 처리
  .anonymous(withDefaults())                   // 익명 사용자 처리
  .servletApi(withDefaults())                  // 서블릿 API와 통합
  .apply(new DefaultLoginPageConfigurer<>())   // 기본 로그인 페이지 설정

 

🔍 설명

메서드  설명
csrf() CSRF 공격 방지용 토큰 기능을 활성화. 폼 전송할 때 꼭 필요
addFilter() Spring 내부 필터를 수동으로 추가. (비동기 작업에 필요한 필터 등)
exceptionHandling() 로그인 실패, 권한 오류 등 보안 예외 처리 방식을 설정
headers() XSS 방지, CORS 등 다양한 보안 관련 HTTP 헤더 설정을 담당
sessionManagement() 로그인 상태 유지, 세션 고정 공격 방지 등을 설정
securityContext() 인증 정보를 SecurityContext에 저장하고 복원하는 기능
requestCache() 로그인 전 요청을 저장했다가, 로그인 후 복원할 수 있도록 처리
anonymous() 로그인하지 않은 사용자도 "익명 사용자"로 간주해서 기본 권한을 부여
servletApi() 서블릿 관련 API(HttpServletRequest 등)를 SecurityContext와 연동
apply(DefaultLoginPageConfigurer) 기본 로그인 페이지를 자동으로 생성. 커스터마이징 안 했을 때 씀

 

✅ SecurityBuilder가 설정 클래스 초기화

private void init() throws Exception {
    Collection<SecurityConfigurer<O, B>> configurers = getConfigurers();
    for (SecurityConfigurer<O, B> configurer : configurers) {
        configurer.init((B) this); // 설정 준비
    }
}

 

🧩 이 모든 설정은 어떻게 등록될까? - 설정 적용

public HttpSecurity csrf(Customizer<CsrfConfigurer<HttpSecurity>> csrfCustomizer) throws Exception {
    ApplicationContext context = getContext();
    csrfCustomizer.customize(getOrApply(new CsrfConfigurer<>(context)));
    return HttpSecurity.this;
}

이런 식으로 각 설정 클래스(Configurer)를 미리 만들어서 적용하는 구조이다.

 

  • getOrApply() → 설정 클래스가 이미 있으면 가져오고, 없으면 새로 만들어 등록
  • withDefaults() → 기본 설정을 자동 적용하는 유틸

🧭 전체 흐름 정리

Spring Security가 초기화될 때 내부에서 일어나는 흐름을 정리하면

 

[1] HttpSecurity 생성 (SecurityBuilder) : 자동 생성에 의해 빌더 클래스(웹 보안을 구성하는 빈 객체랑 설정 클래스)생성

[2] 여러 SecurityConfigurer 등록 (.csrf(), .formLogin() 등)

public interface SecurityConfigurer<O, B extends SecurityBuilder<O>> {
    void init(B builder) throws Exception;
    void configure(B builder) throws Exception;

}

[3] 각 설정 클래스의 init(), configure() 실행 :   필터 생성, 여러 설정을 하고 초기화와 관련된 일을 한다.

[4] build() -> 보안 필터 체인(SecurityFilterChain) 조립 및 적용

 

`SecurityBuilder`는 전체 구조를 조립하고, ` SecurityConfigurer`는 그 안에 들어갈 각각의 보안 설정 모듈을 담당한다

 

 

마치며

제대로 알고 싶어서 하나하나 이런 흐름에 대해서 공부해보는데

너무 어렵다..