[Spring Security] SecurityBuilder 와 SecurityConfigurer

2024. 11. 19. 14:30Framework & Library/Spring Security

 애플리케이션 실행 시 Spring Security 는 어떻게 초기화 될까? 이번에는 초기화에 가장 중요한 역할을 수행하는 SecurityBuilder 와 SecurityConfigurer 에 대해서 알아보자.

1. 설명

1-1. SecurityBuilder 인터페이스

 SecurityBuilder 는 빌더 클래스로서 웹 보안을 구성하는 Bean 객체와 설정 클래스들을 생성하는 역할을 한다. 라이브러리를 통해서 아래와 같은 내용을 확인할 수 있었다.

interface SecurityBuilder<O>
Interface for building an Object

객체 구축을 위한 인터페이스
O build()
Builds the object and returns it or null.
Returns : the Object to be built or null if the implementation allows it.

객체를 구축하고 객체 또는 null 을 반환한다. (null 의 경우 구현 메서드가 허용하는 경우 반환할 수 있다.)

 

즉, 웹 보안 구성을 위한 Bean 객체 및 설정 클래스 객체를 생성한다는 내용으로 이해할 수 있다.

 

1-2. SecurityConfigurer 인터페이스

 SecurityConfigurer 는 Http 요청과 관련된 보안처리를 담당하는 필터들을 생성하고 여러 초기화 설정에 관여하는 역할을 한다. 라이브러리의 내용은 아래와 같다.

interface SecurityConfigurer<O, B extends SecurityBuilder<O>>
Allows for configuring a SecurityBuilder. All SecurityConfigurer first have their init(SecurityBuilder) method invoked. After all init(SecurityBuilder) methods have been invoked, each configure(SecurityBuilder) method is invoked.

SecurityBuilder 를 구성할 수 있다. 모든 SecurityConfigurer 는 먼저 init(SecurityBuilder) 를 호출하고 configure(SecurityBuilder) 를 호출한다.
void init(B builder)
Initialize the SecurityBuilder. Here only shared state should be created and modified, but not properties on the SecurityBuilder used for building the object. This ensures that the configure(SecurityBuilder) method uses the correct shared objects when building. Configurers should be applied here.

SecurityBuilder 를 초기화한다. 공유 상태만 생성/수정해야 하고 객체를 빌드하는데 사용되는 SecurityBuilder 의 속성은 수정하지 않아야 한다. 이렇게 하면 configure(B builder) 가 빌드 시 올바른 공유 객체를 사용하게 된다. 여기에 구성들을 적용해야 한다.
void configure(B builder)
Configure the SecurityBuilder by setting the necessary properties on the SecurityBuilder.

SecurityBuilder 에 필요한 속성을 설정하여 SecurityBuilder 를 구성한다.

 

즉, SecurityBuilder 를 구성하기 위해 init(B builder) 를 호출해 각 구현 클래스(= Configurer 클래스)의 객체를 초기화하고 이후 configure(B builder) 를 호출해 보안처리에 필요한 필터를 생성 및 설정하는 것이다.

 

1-3. SecurityBuilder 와 SecurityConfigurer 의 관계

 그렇다면 두 인터페이스는 결국 어떤 관계일까? 정리하면 SecurityBuilder 가 SecurityConfigurer 를 참조(사용, 활용)하고 있는 형태라 할 수 있다. 초기화 과정을 굉장히 복잡하지만 간략하게 말하면 아래와 같다.

AutoConfiguration(자동설정)
         |
(1) 빌더 클래스 생성
         ↓
SecurityBuilder
         |
(2) 설정클래스 생성
(3) 초기화/설정 작업 진행
         ↓
SecurityConfigurer

 

 

2. 실습

 두 인터페이스에 대한 설명은 위와 같지만 위 설명만으로는 정확하게 초기화가 어떻게 진행되는지 알기에는 무리가 있다. 그래서 디버깅을 통해 어떻게 Spring Security 가 초기화 되는지 확인해 보았다. 앞서 말했듯 Spring Security 초기화는 굉장히 복잡하므로 위에서 설명한 내용을 기준으로 브레이크 포인트를 잡아 확인해 보았다.

 

우선 실습에 사용한 프로젝트는 별다른 보안 설정을 작성하지 않았기에 '기본 보안' 이 적용된 상태이다. 그래서 이전 게시시물에서 이야기한 SpringBootWebSecurityConfiguration.SecurityFilterChainConfiguration 클래스의 defaultSecurityFilterChain() 에 브레이크 포인트를 걸었다.

 

AutoConfiguration(자동 설정)을 통해 생성된 HttpSecurity 객체를 전달 받기에 해당 객체를 확인해보니 여러 설정 클래스 객체가 존재했지만 각 객체에 null 값이 있는 것을 통해 아직 초기화나 설정/필터가 구성된 것은 아니라 생각했다.

HttpSecurity http 의 configurers

 

그리고 이후 formLogin() 과 httpBasic() 을 통해 2개의 설정 클래스가 추가 되어 HttpSecurity.configurers 의 size 가 증가되는 것을 확인했다. 설정 클래스를 추가했기에 해당 필드의 크기가 증가한 것 같다.

 

마지막으로 build() 가 호출되면 doBuild() 가 호출되는데 해당 메서드는 아래와 같다.

AbstractConfiguredSecurityBuilder 추상 클래스의 doBuild()

AbstractConfiguredSecurityBuilder.doBuild()
Executes the build using the SecurityConfigurer's that have been applied using the following steps:
- Invokes beforeInit() for any subclass to hook into
- Invokes SecurityConfigurer. init(SecurityBuilder) for any SecurityConfigurer that was applied to this builder.
- Invokes beforeConfigure() for any subclass to hook into
- Invokes performBuild() which actually builds the Object

다음 단계에 따라 적용된 SecurityConfigurer 를 사용해 빌드를 실행한다.
- 하위 클래스가 연결되도록 beforeInit() 를 호출한다.
- SecurityConfigurer 를 호출한다. 이 빌더에 적용된 SecurityConfigurer 에 대한 init(SecurityBuilder) 이다.
- 연결할 하위 클래스에 대해 beforeConfigure() 를 호출한다.
- 실제로 객체를 빌드하는 PerformBuild() 를 호출한다.

 

즉, 해당 메서드를 통해 설정 클래스들의 초기화 및 설정과 필터 등록이 이루어진다는 것을 알 수 있었다. 빌드의 상태를 수정하며 SecurityConfigurer 의 init() 과 configure() 를 순차적으로 호출해 설정 클래스를 초기화 후 설정 및 필터 생성/등록을 하는 것이다.

 

모든 작업을 마친 HttpSecurity 를 반환하면 이제 Build 가 완성이 되고 Bean 으로 SecurityFilterChain 이 등록되는 것이다.

 

 

3. 마무리

 솔직히 강의를 따라해보고 이런저런 생각을 해보았지만 아직 완벽하게 이해가 된 것은 아니다. 하지만 크게 보았을 때 설정 클래스들을 SecurityBuilder 가 생성하고 SecurityConfigurer 를 사용해 생성한 객체를 초기화 및 설정을 구성Spring Security 의 초기화 작업이 이루어진다는 것을 알 수 있었다.

 

아직 남은 강의가 많기에 천천히 해당 내용을 정리해볼 생각이다.


참고 강의/문서