Spring Security?
Spring Security는 간단한 형태의 Servlet Filter를 통해서 자바 웹 애플리케이션에 대한
인증과 권한 (Authentication & Authorization)을 제공하는 Spring의 보안 Framework이다.
Spring Security의 큰 특징으로는
각각의 역할에 맞는 필터를 체인으로 구축하여 순서에 따라 실행된다는 점이다.
그리고 모든 Request는 반드시 이 필터 체인을 거쳐야 한다.
그리고 이 필터를 개발자가 선택하여 필요에 맞게 커스터마이징 할 수 있다.
아래의 SecurityConfig 클래스 내부의 SecurityFilterChain 메서드 안에서 ( . )으로 이어지는
부분이 필터의 체인을 구현하고 있는 모습이다.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class SecurityConfig {
@Bean // 패스워드 암호화
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
http.csrf().disable(); //form태그로만 요청 가능 (postman요청 불가)
http.headers().frameOptions().disable(); //h2연결을 위함
http.authorizeRequests()
.antMatchers("/user/**").authenticated()
.antMatchers("/manager/**").access(//권한 부여
"hasRole('ROLE_ADMIN')")
.antMatchers("/admin/**").access( //권한 부여
"hasRole('ROLE_ADMIN')")
.anyRequest().permitAll()
.and()
.formLogin()
.loginPage("/login");
return http.build();
}
}
Filter - Servlet Container
Client 측에서 HTTP 요청이 들어오게 되면 서블릿 컨테이너가 [Filter]와 [Servlet]이 들어있는
FilterChain을 생성하여 필터와 서블릿이 해당 요청을 처리하게 된다.
* Spring MVC에서 Servlet은 DispatcherServlet의 인스턴스이다.
하나의 Servlet은 한 번에 하나의 HttpServletRequest / Response만 다룰 수 있지만,
하나 이상의 Filter는 다음과 같이 사용될 수 있다.
- Downstream 필터들과 서블릿의 호출을 막는다. (보통 HttpServletResponse의 경우)
- Downstream 필터들과 서블릿에 의해 처리되는 HttpServletResponse / Request의 수정
Downstream
일반적인 방식의 Top-Down으로 코드가 진행되는 순서
중요 포인트
Filter는 downstream 필터들과 서블릿에만 영향을 끼치기 때문에
Filter의 호출 순서가 매우 중요하다.
Filter - Spring Security
Spring Security에서는 [DelegatingFilterProxy]를 상속받은 필터를 FilterChain안에 사용해서
[FilterChainProxy]라는 특별한 필터를 만들 수 있다.
FilterChainProxy는 Bean으로 간주되지만 일반적으로 DelegatingFilterProxy안에 래핑 된다.
DelegatingFilterProxy
Servlet컨테이너의 Life-Cycle과 스프링의 ApplicationContext를 연결하는 역할
서블릿 컨테이너는 스프링 컨테이너(ApplicationContext)의 빈을 이용할 수 없기 때문에
중간에 끼여서 연결해주는 역할이라고 생각하자.
FilterChainProxy를 통하여 다시 여러 개의 [Security Filter]라고 불리는 filter인스턴스들을
[SecurityFilterChain]이라는 그룹으로 묶어서 사용할 수 있다.
SecurityFilterChain은 여러개를 구축할 수 있고 또한 그 안의 Security Filter의 개수 또한
그림처럼 3개가 아니고 n개가 될 수 있다.
SecurityFilterChain은 가장 먼저 조건에 맞는 Chain만을 호출하는 점이 중요하다.
예를들어 /api/getsomething이라는 주소로 Request가 왔다면, n번째 SecurityFilterChain의 조건도
부합하지만 0번째 SecurityFilterChain도 조건에 맞고 순서상 먼저 이므로 0번째 녀석만 호출된다.
즉,
다수의 SecurityFilterChain이 있다면 각각의 SecurityFilterChain은 유니크하고 서로 독립적이
되도록 구축할 수 있다.
응용하면 URI에 따라 어떤 SecurityFilterChain을 호출할지 지정할 수 있다.
SecurityFilterChain안에 Security Filter가 아예 없도록 만들 수도 있는데 이 경우는 스프링 시큐리티가 특정
Request를 무시하도록 할때 사용한다.
Architecture :: Spring Security
Spring Security’s Servlet support is based on Servlet Filters, so it is helpful to look at the role of Filters generally first. The picture below shows the typical layering of the handlers for a single HTTP request. The client sends a request to the appl
docs.spring.io
'programming > SPRING' 카테고리의 다른 글
싱글톤 사용시 주의사항 (0) | 2022.08.03 |
---|---|
Spring MVC (0) | 2022.07.13 |
Spring Data JDBC 간략 요약 (0) | 2022.06.30 |
JDBC 간단 요약 (0) | 2022.06.30 |
예외 처리 (0) | 2022.06.29 |