728x90

필자의 환경은

- Spring Boot 3.xxx 

- Spring Security 6.xxx

 

시작전에 그래도 스프링 문서에있는 그림을 보자

 

 

 

그림은 좌에서 우로 설명된 기분이지만

실제 코드는 우에서 좌로 가야한다.. (알맹이부터...)

 

우선 라이브러리를 끼자

implementation 'org.springframework.boot:spring-boot-starter-security'

 

 

그리고 적당히 UserDetailsService나 PasswordEncoder 나 SecurityFilterChain Bean 등록하는 코드 적어둔다음

 

서버를 재시작하면서 디버깅하면된다.

 

스프링시큐리티의 내부로직은 너무 방대하기

이번 게시글에서는 제목대로 HttpSecurity, WebSecurity 이 두개에만 포커스를 맞춰보자

 

#1. HttpSecurityConfiguration 의 httpSecurity() 로 시작 (단, @Scope("prototype") )

@Scope("prototype") 이기 때문에 주입이 필요할때마다 동작한다

 

 

 

#1-2. AuthenticationConfiguration의 getAuthenticationManager() : AuthenticationManager (= ProviderManager)

AuthenticationManagerBuilder 객체를 생성하여 ProviderManager 를

parentAuthenticationManager 메서드를 통해 부모 인증관리자로 저장한다

 

 

 

 

 

#1-2-1 AuthenticationManagerBuilder의 performBuild() : ProviderManager

위의 #1-2 에서 AuthenticationManager  객체를 생성할때 실제 위임을 받아서 

authBuilder.build() 로직을 타고 가다보면 결국 도착한다 (생략)

ProviderManager 를 빌드를 수행한다

 

 

즉, #1-2 전체과정으로 인증 관리자를 생성했다.

그리고  AuthenticationManagerBuilder  의 부모 인증 관리자로 지정했다.

 

 

#1-3 HttpSecurity 의 생성자 호출

 

 

 

HttpSecurity 의 생성자를 호출 함으로서 눈여겨 볼것은

this.setSharedObject 이다,

인증관리자의 구현직전의 빌더와 몇가지 객체를 공유객체로 따로 저장하는 것을 볼 수있다

따라서 HttpSecurity 를 주입받으면 저 공유객체속 인증관리자 빌더를 꺼내서 우리가 원하는

Provider 들을 지정할 수 있다

 

 

 

그리고 AuthenticationManagerBuilder를 아까

parentAuthenticationManager 메서드를 통해 부모 인증관리자로 저장했던걸 확인할 수 있다

그리고 AuthenticationManagerBuilder 속 parentAuthenticationManager 필드의 providers 을 보면

DaoAuthenticationProvider 가 있다,  이런 인증관리자 내부에 List로 가지고 있는 요소를

프로바이더(Provider) 라고 부른다 

실제 인증로직의 핵심을 담당한다. 매니저는 위임을 할뿐이다. (참고)

 

 

 

 

다음으로 HttpSecurity 자체가 갖고있는 AuthenticationManager 를 보면

아직 null 인것을 알 수 있고, 공유 객체는 잘들어와 있다

 

 

 

 

*참고

sharedObjects 는 Map이다

 

 

*참고 

DaoAuthenticationProvider 은 UserDetailsService를 통해 사용자를 조회하는 역할을 한다

 

 

여기까지만 해도 정말 내가 코드친게 없는데 이루어지는 로직이다

이제부터가 시작이다 !

 

#2. 개발자가 생성한 @Bean SecurityFilterChain 이 HttpSecurity  를 주입 받는다

이때 #1의 전체 과정의 HttpSecurity 를 주입 받는다 

 

그렇다면 위의 과정을 통해 얻은 것은 다음과 같다

 

[첫번째]

부모 인증관리자도 생성되었을것이며 타입은 정확하게 ProviderManager 일것이다

 

[두번쨰]

 

공유객체는 세개가 저장되어 있었고

우리의 주인공은  AuthenticationManagerBuilder  였다  AuthenticationManager가 되기 직전의 형태라고 보자

 

 

#2. 개발자가 생성한 @Bean SecurityFilterChain 내부

주입받은 HttpSecurity를 build() 하면

최종적으로 HttpSecurity 의 performBuild() 가 호출된다 

리턴 타입은 DefaultSecurityFilterChain  이다

 

 

 

이렇게 필터들을 갖은 하나의 SecurityFilterChain이 생성된다

 

 

 

 

#3. WebSecurityConfiguration 의 setFilterChains 메서드 호출

#2 에서 만들 SecurityFilterChain을 리스트로 갖는 컬렉션을 주입받는다

참고로 SecurityFilterChain은 여러개 생성할 수 있으니 컬렉션으로 받는다

 

 

 

#3. WebSecurityConfiguration 의 springSecurityFilterChain 메서드 호출

정확히 FilterChainProxy 을 생성하기 위함이다 ( FilterChainProxy 은 GenericFilterBean 을 상속한다 )

 

#3. WebSecurity의 performBuild() 메서드 호출 (최종적으로)

앞서 build 하면 결국 WebSecurity 의 performBuild() 메서드가 호출되는데

모든 보안설정들을 가지고있는 FilterChainProxy 를 생성한다

 

 

그러면 스프링 시큐리티 문서와 닮은 그림이 나온다

 

 

 

혼자 공부할겸 한번 글을 작성해봤는데

 

도움이 될지 모르겠다.

728x90

'개발 > spring-security' 카테고리의 다른 글

rememberMe 에 대하여  (4) 2024.10.26
jwt 토큰 생성하고 검증해보자  (0) 2024.06.01
spring security 와 jwt 주저리  (0) 2024.06.01
JWT 토큰  (0) 2024.06.01
커스텀 Filter 에 AuthenticationManager 공유하기  (0) 2024.05.23

+ Recent posts