BackEnd/Spring Security

[Spring Security] 필터 초기화와 다중 보안 설정

샤아이인 2022. 8. 25.

본 글은 Spring Security docs 와 여러 블로그 들을 참고하고, 공부하면서 요약하였습니다.

 

1. 필터 초기화와 다중 보안 설정

스프링 시큐리티에서는 보안 설정을 단일 설정이아닌 여러 개의 설정을 만들어서 동시에 사용을 할 수 있다.

 

출처 - https://catsbi.oopy.io/f9b0d83c-4775-47da-9c81-2261851fe0d0

위 그림을 보면 Config 파일이 2개이다. 설정 Config Class 별로 보안기능이 각각 작동한다.

 

각 Config Class 별로 RequestMatcher를 설정한다. 예를 들면 다음과 같이 말이다.

http.antMatcher("/admin/**")

이후 각각의 config 파일 별로 Filter가 생성된다.

 

위에서 생성된 Filter를 DefaultSecurityFilterChain 내부에 필드로 보관하고있게 된다.

위 그림에서 본것처럼 filters, requestMatcher 를 필드로 가지고있다.

 

이후 Client의 요청이 오면 RequestMatcher와 매칭되는 필터가 작동하게됩니다.

예를 들어 다음 그림을 살펴보시죠!

 

1. GET 메서드로 "/admin"의 리소스에 접근하려 합니다.

2. 이를 FIlterChainProxy에서 요청을 받아 요청을 위임시킬 필터를 선택하게 됩니다.

3. 요청 URL과 matches를 하여 true가되는 Filter를 선택합니다.

 -> FilterChainProxy가 저장하고있는 각각의 SecurityConfig 객체들에서 RequestMacher의 정보와 매치되는 정보를 찾게됩니다.

4. 일치하는 객체의 필터를 수행하여 인증/인가 처리를 한다.

 

2. 디버깅 해보기

우선 설정파일 2개를 다음과 같이 만들어보자.

 

▶ SecurityConfig

@Order(0)
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .antMatcher("/admin/**")
                .authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .httpBasic();
    }
}

 

▶ SecurityConfig1

@Order(1)
@Configuration
public class SecurityConfig2 extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .anyRequest().permitAll()
                .and()
                .formLogin();
    }
}

 

이후 애플리케이션을 실행시켜보면 다음과 같이 FilterChainProxy 객체를 만드는 과정을 살펴볼 수 있다.

이때 생성자의 인자로 "securityFilterChains"를 전달받고 있다.

디버깅을 해보니 size 2짜리의 ArrayList 이다.

 

Config에서 설정한 정보를 바탕으로 생성된 SecurityFilterChain들을 전달받는 것 이다.

 

▶ 사용자 요청시

다음으 주소로 사용자가 요청을 보내온다고 해보자.

http://localhost:8080/

 

맨처음 이를 받는 부분은 FilterChainProxy가 받게 된다. doFilterInternal() 을 살펴보자. 

디버깅 해보면 위 빨간 박스 안처럼 FilterChain 2개를 FilterChainProxy를 가지고 있다.

이중 필요한 FilterChain을 찾기위해 getFilters() 메서드를 실행한다.

 

- getFilters()

내부에서 chain을 대상으로 matches()를 적용해서 사용가능한 Filter인지 확인한다.

 

사용자의 요청을 "/" 로 요청이 들어왔는데, 해당 필터의 RequestMatcher가 "/admin/**"이라 적용되지 않는다.

위 사진에서 하단의 chain 부분을 보면 [RequestMatcher=Ant [pattern=/admin/**']이 된다.

 

다음으로는 config2 의 FilterChain과 matches()를 해보게 된다. 이때는 true가 된다.

 

따라서 해당 FilterChains에 있는 filter들을 사용하게 된다.

 

마지막으로 시퀀스 다이어그렘을 살펴보자.

 

참고

https://catsbi.oopy.io/f9b0d83c-4775-47da-9c81-2261851fe0d0

 

스프링 시큐리티 주요 아키텍처 이해

목차

catsbi.oopy.io

 

 

댓글