Spring Security
Spring Security는 Spring에서 사용자 인증/인가를 쉽게 할 수 있도록 제공하는 프레임워크이다.
기본적으로는 세션 기반 인증을 제공한다.
Spring Security는 인증과 인가에 대해 서로 분리된 전략을 사용한다.
인증에 대해서는 AuthenticationManager가 가장 책임을 많이 지고 있다.
AuthenticationManager의 authenticate() 메서드는 input(ID/PW)이 유효한 principal인지 '인증'하는 역할을 수행한다.
가장 대표적인 AuthenticationManager의 구현체는 ProviderManager이다.
Provider Manager는 AuthenticationProvider 인스턴스들의 chain을 대표하고 있다. AuthenticationProvider는 주어진 Authentication은 지원하는 지 확인할 수 있는 메서드를 가진 AuthenticationManager라고 보면 된다.
즉, ProviderManager는 여러 개의 AuthenticationProvider를 관리함으로써 다양한 종류의 인증 로직을 chain 형식을 관리할 수 있다는 것이다.
ProviderManager는 자기들끼리 상속 관계를 이루며, 자식 ProviderManager가 특정 input에 대하여 어떤 AuthenticationProvider에서도 인증을 못한다면 부모 Provider Manager로 넘어간다. 만약 부모 객체도 이를 처리하지 못한다면 AuthenticationException이라는 RuntimeException이 발생한다.
이렇게 계층 구조를 이루게 되는 이유는 자식 객체들은 특정 리소스 그룹에 대해 고유한 인증 주체로 분리하고 그 자식 객체들이 공통적인 부모를 공유할 수 있도록 하기 위함이다.
HTTP로 소통하는 Spring 웹 서버에서는 클라이언트가 어플리케이션에 요청을 보내면
컨테이너는 요청 URI에 따라 어떤 필터와 어떤 서블릿으로 이를 처리할지 결정한다.
대부분의 경우 하나의 서블릿이 하나의 요청을 처리하지만
filter는 정해진 순서에 따라 chain의 형태로 연결되어있기 때문에 여러개의 filter들이 순서대로 요청을 처리하게 된다.
Spring Security는 이 체인에서 하나의 filter로 존재하며, 이 구현체의 타입은 FilterChainProxy이다.
Spring boot에서는 security filter가 하나의 bean으로 존재하며 모든 요청을 처리하기 위해 기본적으로 설치된다.
Spring Security는 하나의 filter이긴 하지만 그 안에는 추가적인 filter들이 존재하며 각자의 고유한 역할들이 정해져있다.
따라서 이 FilterChainProxy 객체의 고유한 이름은 SpringSecurityFilterChain이다.
사실 이 Spring SecurityFilterChain은 하나의 chain만 뿐만 아니라,
요청의 path에 따라 달리 매칭될 수 있는 여러 개의 chain으로 존재할 수 있다.
다만, 반드시 하나의 요청이 이들 중 하나의 chain에 매칭된다면
오직 이 하나의 chain만이 그 요청을 처리해야 하며 다른 chain으로 요청이 넘어갈 수는 없다.
이렇게 여러 개의 filter chain을 두면 리소스의 그룹에 따라서 다른 방식의 인증/인가를 처리할 수가 있게 된다.
(예시 - '/match1/**'에 대해서는 cookie-based, '/match2/**'에 대해서는 token-based)
우리는 이 chain을 커스텀하거나 아예 새로 만드는 방식으로 Spring Security를 사용할 수가 있다.
Spring Boot에서 기본적으로 사용하는 default fallback filter chain('/**' path와 매칭될 filter chain)을
그대로 fallback으로 사용하면서 새로운 filter chain을 만드려면
WebSecurityConfigurerAdapter(혹은 WebSecurityConfigurer) 타입의 bean을 추가하면 된다.
filter의 순서를 지정하고 싶다면 @Order를 사용할 수도 있다.
@Configuration
@Order(SecurityProperties.BASIC_AUTH_ORDER - 10)
public class ApplicationConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/match1/**")
...;
}
}
위와 같이 작성하면 fallback chain 앞에 하나의 새로운 filter chain이 더 생기는 것이다.
실제로 해당 chain이 어떤 필터를 거치는 지 모니터링하고 싶다면
아래와 같이 @EnableWebSecurity(debug = true)를 설정해주면 된다.
출처 : https://eungeun506.tistory.com/137
Spring Security를 이용한 JWT 로그인 1 - JWT, Spring Security
Monkey Penthouse라는 창업을 앞두고 있는 프로젝트의 백엔드를 맡게 되었고, 이 프로젝트의 메인 서비스가 될 어메니티/결제 기능 구현에 앞서 인증/인가 기능부터 구현하게 되었다. Monkey Penthouse의
eungeun506.tistory.com