[Spring Security] HttpSecurity 와 WebSecurity

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

 이전 강의를 통해 Spring Security 의 초기화에 대해 알수 있었는데 해당 내용이 전부는 아니다. 이번 게시물을 통해 나머지 부분에 대한 내용을 좀 더 알아보려 한다.

1. HttpSecurity 와 SecurityFilterChain

 현재 프로젝트는 자동 설정을 통해 기본 보안이 적용된 상태이다. 그래서 SpringBootWebSecurityConfiguration.SecurityFilterChainConfiguration 클래스의 defaultSecurityFilterChain() 를 사용하게 된다. 해당 메서드는 파라미터로 HttpSecurity 객체를 받는데 해당 객체는 어떻게 생성되어 전달되는 걸까?

 

답은 'org.springframework.security.config.annotation.web.configuration' 패키지의 HttpSecurityConfiguration 클래스에 있었다. 해당 클래스는 HttpSecurity 객체를 생성해 Bean 으로 등록한다. 물론 객체를 생성하는 과정에서 설정 클래스(= Configure Class) 객체들을 생성한다(아직 초기화 및 설정, 필터 생성은 X).

 

이 상태에서 defaultSecurityFilterChain() 에서 HttpSecurity 를 build() 하게 되면 최종적으로 보안에 필요한 설정 클래스를 초기화하고 필터들을 생성해 SecurityFilterChain 을 Bean 으로 등록하게 된다. 아래는 디버깅을 통해 확인한 SecurityFilterChain 이다.

WebSecurity 에서 확인한 SecurityFilterChain

 

그런데 분명 나는 SecurityFilterChain 을 Bean 으로 등록했다 생각했는데, DefaultSecurityFilterChain 은 어디서 튀어 나온 걸까?

 

사실 DefaultSecurityFilterChain 은 네이밍에서 유추할 수 있는 것처럼 SecurityFilterChain 인터페이스의 구현 클래스이다.

DefaultSecurityFilterChain 클래스

 

SecurityFilterChain 인터페이스는 getFilters() 와 matches() 를 가지고 있어 해당 메서드들을 구현해 주어야 한다. 각 메서드는 아래와 같은 용도로 사용된다.

boolean matches(HttpServletRequest request)
- 요청이 현재 SecurityFilterChain 에 의해 처리되어야 하는지 여부를 결정
- true 라면 요청에 해당 필터 체인에 의해 처리되어야 함을 의미한다. false 라면 다른 필터 체인이나 로직에 의해 처리되어야 함을 의미한다.
- 이를 통해 요청별로 적절한 보인 필터링 로직이 적용될 수 있다.

List<Filter> getFilters()
- 현재 SecurityFilterChain 에 포함된 Filter 객체의 리스트를 반환한다.
- 메서드를 통해 현재 필터 체인에 어떤 필터들이 포함되어 있는지 확인 가능하며, 각 필터는 요청 처리 과정에서 특정 작업(인증, 권한 부여, 로깅 등)을 수행하게 된다.

 

위와 같은 내용을 통해 현재 SecurityFilterChain 은 DefaultSecurityFilterChain 이라는 것을 알 수 있었다.

 

 

2. WebSecurity 와 FilterChainProxy

 시작말에서 언급했다 싶이 SecurityFilterChain 을 Bean 으로 등록하는 것이 Spring Security 초기화 작업의 끝이 아니다. 이 내용을 설명하기 위해 알아햐 하는 것이 바로 WebSecurity 이다.

 

일단 HttpSecurity 와 유사하게 WebSecurity 또한 WebSecurityConfiguration 에서 생성 및 초기화 된다. HttpSecurity 가 build() 를 통해 SecurityFilterChain 을 생성해 Bean 으로 등록했다면 WebSecurity 는 build() 를 통해 FilterChainProxy 를 생성해 Bean 으로 등록한다.

 

또한 WebSecurity 는 HttpSecurity 에서 생성한 SecurityFilterChain 빈을 SecurityBuilder 에 저장한다. 이 과정을 WebSecurity 필드의 securityFilterChainBuilders 를 통해 알 수 있었다. 이후 build() 호출시 SecurityBuilder 에서 SecurityFilterChain 을 꺼내 FilterChainProxy 생성시 파라미터로 전달한다.

 

디버깅을 통해 아래와 같이 FilterChainProxy 가 생성되고 해당 객체 필드인 filterChains 에 SecurityFilterChain 이 존재한다는 것을 확인할 수 있었다.

WebSecurity 디버깅

 

위 이미지를 보면 filterChains 에 DefaultSecurityFilterChain 이 있는 것을 볼 수 있다.

 

여기까지가 Spring Security 의 초기화 작업이라고 한다. 즉, SecurityFilterChain 을 Bean 으로 등록하고 WebSecurity 가 SecurityFilterChain 을 파라미터로 사용해 FilterChainProxy 를 생성/Bean 으로 등록하는 것이 Spring Security 초기화의 목적이라 할 수 있는 것 같다.

 

 

3. 마무리

 이전 게시글부터 시작해서 해당 게시글까지 Spring Security 초기화에 대한 내용을 정리하였는데, 아직 완벽하게 이해하지는 못한 것 같다. 하지만 강의에서는 초기화 과정은 굉장히 복잡하니 큰 맥락을 이해하는 것을 권장하고 있다. 그런 점에서 보았을 때, Spring Security 에서 보안 처리(인증/인가)에 사용되는 객체와 필터들이 어떻게 생성되는지 큰 틀은 이해했다고 생각한다.

 

당장에 전부 이해하려고 하기보다는 이후 강의를 통해서 이전 내용을 잘 못 알았다면 다시 알고 맞다면 해당 내용을 기반으로 이후 내용도 이해할 것이다.


참고 강의/문서