프로젝트 생성 / 의존성 추가
프로젝트 구성
-
기본 구성
- Spring Boot 3.x
- JDK 17
- Gradle
-
의존성 주입
- spring-boot-starter-web
- spring-boot-starter-security
자동 설정에 의한 보안 작동
- 서버가 기동되면 스프링 시큐리티의 초기화 작업 및 보안 설정이 이루어짐
- 별도의 설정이나 코드를 작성하지 않아도 기본적인 웹 보안 기능이 작동
1) 인증여부 검증 -> 인증 승인 -> 자원 접근 가능
2) 인증 방식: form 로그인, httpBasic 로그인
3) 로그인 페이지 자동 생성
4) 인증 승인 가능한 계정 1개 기본 제공
- username: user
- password: 랜덤 문자열
- SecurityProperties 설정 클래스에서 생성!
@Bean
@Order(SecurityProperties.BASIC_AUTH_ORDER)
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests((requests) -> requests.anyRequest().authenticated());
http.formLogin(withDefaults());
http.httpBasic(withDefaults());
return http.build();
}
*이 두 가지 설정 파일만 잘 이해하고 있어도 스프링 시큐리티 초기화 작업에 대해서 파악할 수 있다.
1. 시큐리티 Builder
- 빌더 클래스
- 웹 보안 구성하는 빈 객체, 설정 클래스 생성
- WebSecurity, HttpSecurity 가 있음
2. 시큐리티 Configurer
- 여러 초기화 설정 관여
- Http 요청과 관련된 보안처리를 담당하는 필터 생성
- 스프링 시큐리티는 모든 인증, 인가 요청을 필터를 통해서 함
=> "필터" 기반 보안
HttpSecurity / WebSecurity
HttpSecurity
- HttpSecurityConfiguration 에서 HttpSecurity 생성, 초기화
- 보안에 필요한 각 설정 클래스와 필터 생성
- SecurityFilterChain 빈 생성
1. boolean matches(HttpServletRequest request) : 필터 체인 처리 여부 확인
2. List getFilters() : 필터 객체 리스트 반환, (인증, 권한 부여, 로깅 등 수행)
WebSecurity
- WebSecurityConfiguration 에서 WebSecurity 를 생성, 초기화
- WebSecurity 는 HttpSecurity 에서 생성한 SecurityFilterChain 빈을 SecurityBuilder 에 저장
- WebSecurity 가 build() 를 실행하면 SecurityBuilder 에서 SecurityFilterChain 을 꺼내어 FilterChainProxy 생성자에게 전달
- HttpSecurity 에서 생성한 SecurityFilterChain 빈을 SecurityBuilder 에 저장 후 빌드
- SecurityBuilder 에서 SecurityFilterChain 을 꺼내어 FilterChainProxy 생성자에게 전달
DelegatingFilterProxy / FilterChainProxy
Filter
- 서블릿 필터는 웹 애플리케이션에서 클라이언트의 요청(HttpServletRequest)과 서버의 응답(HttpServletResponse)을 가공하거나 검사하는데 사용
- 클라이언트의 요청이 서블릿에 도달하기 전 or 서블릿의 응답을 클라이언트에 보내기 전에 특정 작업을 수행
- 서블릿 컨테이너(WAS)에서 생성, 실행, 종료

- 필터는 선택사항
- init() -> doFilter() -> destroy()

DelegatingFilterProxy
- DelegatingFilterProxy 는 스프링에서 사용되는 특별한 서블릿 필터로, 서블릿 컨테이너와 스프링 애플리케이션 컨텍스트 간의 연결고리 역할을 하는 필터임
- DelegatingFilterProxy 는 서블릿 필터의 기능을 수행하는 동시에 스프링의 의존성 주입 및 빈 관리 기능과 연동되도록 설계된 필터
- DelegatingFilterProxy 는 “springSecurityFilterChain” 이름으로 생성된 빈을 ApplicationContext 에서 찾아 요청을 위임함
- 실제 보안 처리를 수행하지 않음

- 필터의 기능 + spring의 DI, AoP 같은 기능 처리하려고 만든 것
- Spring IOC Container 에서 springSecurityFilterChain 빈을 찾아서 클라이언트의 요청을 위임함. 그러면 Spring Bean이 필터를 구현함
FilterChainProxy
- springSecurityFilterChain 의 이름으로 생성되는 필터 빈으로서 DelegatingFilterProxy 으로 부터 요청을 위임 받고 보안 처리 역할을 한다
- 내부적으로 하나 이상의 SecurityFilterChain 객체들을 가지고 있으며 요청 URL 정보를 기준으로 적절한 SecurityFilterChain 을 선택하여 필터들을 호출한다
- HttpSecurity 를 통해 API 추가 시 관련 필터들이 추가된다
- 사용자의 요청을 필터 순서대로 호출함으로 보안 기능을 동작시키고 필요 시 직접 필터를 생성해서 기존의 필터 전.후로 추가 가능하다

사용자 정의 보안 설정하기
직접 SecurityConfig 생성
- SecurityConfig 클래스 생성 후 @EnableWebSecurity 선언
- 설정 코드는 람다로 작성!(스프링 시큐리티 7버전 부터는 람다 형식만 지원)
- SecurityFilterChain 을 빈으로 정의하면 자동 설정에 의한 빈은 생성되지 않음!
@EnableWebSecurity
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
.formLogin(Customizer.withDefaults());
return http.build();
}
}
사용자 추가 설정
- application.yml 파일에 설정
spring:
security:
user:
name: user
password: 1111
roles: USER
- 자바 설정 클래스에 직접 정의
@Bean
public UserDetailsService userDetailsService() {
UserDetails user = User.withUsername("user")
.password("{noop}1111")
.roles("USER").build();
UserDetails user2 = User.withUsername("user2")
.password("{noop}1111")
.roles("USER").build();
UserDetails user3 = User.withUsername("user3")
.password("{noop}1111")
.roles("USER").build();
return new InMemoryUserDetailsManager(user, user2, user3);