1) 스프링 시큐리티 활용
스프링 부트 프로젝트에 의존 관계를 추가한다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
spring-boot-starter-security
- 스프링 시큐리티를 적용하는 데 필요한 모든 라이브러리를 포함하고 있다.
- 기본적으로 로그인 페이지, 계정 이름, 비밀번호를 만들어주나 커스터마이징도 가능하다.
실행 후 http://localhost:8080/index 에 접근하면 index 페이지가 아닌 로그인 페이지가 표시되는 것을 볼 수 있다.
로그인에 필요한 계정 이름은 user 이고, 패스워드는 애플리케이션 실행 시 스프링 시큐리티가 자동으로 만들어서 로그에 표시해준다.
로그인에 성공하면 index 페이지를 볼 수 있다.
스프링 시큐리티는 기본으로 로그아웃 기능을 수행하는 /logout 엔드포인트를 제공한다.
http://localhost:8080/logout 에 접근하면 로그아웃을 할 수 있다.
2) 필터, 필터체인과 스프링 시큐리티
Filter
- 3개의 메서드가 존재한다.
- inti() : 서블릿 컨테이너가 필터를 등록하는 초기화 과정에서 호출된다.
- doFilter() : 필터의 실질적인 작업을 수행하는 메서드로서 요청, 응답, FilterChain 객체에 접근할 수 있다. FilterChain은 필터의 작업이 완료된 후 체인에 있는 다음 필터를 호출한다.
- destroy() : 서블릿 컨테이너가 필터를 제거할 때 호출된다.
FilterChain
- 체인에 있는 여러 필터를 연쇄적으로 거쳐서 흘러가게 만드는 역할을 한다.
- 필터는 자신의 작업이 완료되는 FilterChain을 호출해 요청이 다음 필터를 통과하게 만든다.
- 요청이 체인상에 있는 마지막 필터를 통과하면 실제 리소스에 접근하게 된다.
스프링 시큐리티의 핵심은 필터에 기반을 두고 있다.
DelegatingFilterProxy, FilterChinProxy
- 스프링 시큐리티의 주요 필터이다.
- HTTP 요청이 스프링 시큐리티 인프라스트럭처를 통과하게 만드는 진입점 역할을 한다.
3) 스프링 시큐리티 아키텍처
DelegatingFilterProxy
- 서블릿 필터는 스프링에서 정의된 빈을 주입받아 사용할 수 없어 이를 해결하기 위해 등장 했다.
- 요청을 스프링 시큐리티의 FilterChainProxy에 위임하는 역할을 한다.
FilterChainProxy
- 스프링 빈으로 등록된다.
- DelagatingFilterProxy로 부터 요청을 받아, 해당 요청을 처리하기 위한 적절한 SecurityFilterChain을 선택한다.
- 하나 이상의 SeceurityFilterChain을 가질 수 있다.
- SecurityFilterChain으로 요청을 흘려보내서 SecurityFilterChain에 있는 필터를 통과하게 만든다.
SecurityFilterChain
- 보안 필터들의 체인을 정의하고 관리하는데 사용된다.
- 다중 SecurityFilterChain을 지원한다.
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/home").permitAll()
.antMatchers("/mypage").authenticated()
.anyRequest().authenticated()
return http.build();
}
}
4) 사용자 인증
SecurityContextHolder
- SecurityContextHolder : SecurityContext 인스턴스를 현재 실행 중인 스레드에 연동한다.
- SecurityContext : 사용자 식별에 필요한 상세 정보가 담겨있다.
- Principal : 사용자 정보
- Authorities : 사용자 권한
AuthenticationFilters
- 사용자 정보를 인증하는 데 사용되는 인증 필터
- 인증 필터가 사용자 정보를 인증하면 SecurityContext에 인증 토큰을 저장하며, 인증 토큰은 필터 체인상에 있는 다른 필터에서 사용할 수 있다.
ExceptionTranslationFilter
- 인증 처리 과정에서 발생한 예외를 처리하는 데 핵심적인 역할을 담당한다.
UserDetailsService
- 사용자별 데이터를 스프링 시큐리티의 UserDetails 객체로 매핑해주는 역할을 담당한다.
AuthenticationProvider
- 실제 인증 처리를 담당하며 인증 요청 객체를 받아서 인증 과정을 수행하고 인증 정보가 담긴 Authentication 객체를 반환한다.
- 인증에 실패하면 AuthenticationException을 던진다.
스프링 시큐리티 인증 과정
- 요청이 처음 들어오면 인증 필터를 거친다. 서버에 설정된 보안 전략에 따라 적절한 인증 필터가 요청을 처리한다.
- 인증 필터는 요청에 포함된 정보를 토대로 인증 토큰을 생성한다.
- 인증 필터는 인증 토큰을 인자로 전달하면서 AuthenticationManager의 authenticate() 메서드를 호출한다.
- AuthenticationManger는 실제 인증 처리 서비스를 제공하는 AuthenticationProvider 인스턴스 목록을 가지고 있다. AuthenticationProvider 인터페이스에는 supports(), authenticate() 두가지 메서드가 있다.supports() 메서드가 true를 반환하면 authenticate() 메서드가 호출되면서 인자로 받은 인증 토큰으로 인증 작업을 수행한다.
- supports() 메서드는 인증 토큰을 인자로 받아서 AuthenticationProvider 인스턴스가 이 인증을 처리할지를 판별해서 boolean 값을 반환한다.
- AuthenticationProvider의 authenticate() 메서드는 인자로 받은 인증 토큰에서 username 값을 추출해서 UserDetailsService 구현체의 loadUserByUsername() 메서드에 인자로 전달하면서 호출한다.
- UserDetailService의 loadUserByUsername()은 인자로 받은 username으로 사용자 정보 저장소를 조회해서 사용자 권한, 비밀번호 등 계정 관련된 정보를 UserDetails에 담아 AuthenticationProvider에게 반환한다.
- AuthenticationProvider는 반환받은 UserDetails에 담겨 있는 정보를 토대로 인증 작업을 수행하고 인증이 성공하면 Authentication을 AuthenticationManager에게 반환한다.
- AuthenticationManager는 반환받은 Authentication에서 비밀 정보를 삭제하고 Authentication을 인증 필터에 반환한다.
- 인증 필터는 반환받은 Authentication을 SecurityContextHolder에 저장하고 응답을 반환한다.
5) 스프링 시큐리티 자동 구성
아래 세개의 설정 클래스를 사용해서 스프링 시큐리티 자동 구성을 수행한다.
- SecurityAutoConfiguration
- UserDetailsServiceAutoConfiguration
- SecurityFilterAutoConfiguration
SecurityAutoConfiguration
- 스프링 시큐리티 자동 구성에서 중심점 같은 역할을 담당한다.
- SpringBootWebSecurityConfiguration, WebSecurityEnablerConfiguration, SecurityDataConfiguration 세 개의 클래스를 사용해서 자동 구성을 수행한다.
- SpringBootWebSecurityConfiguration
- 스프링 시큐리티 라이브러리가 클래스패스에 있지만 개발자가 커스텀 시큐리티 설정을 추가하지 않았을 때 사용된다
- 폼 로그인 기능과 HTTP 기본 인증 기능을 포함하는 SecurityFilterChain 빈을 생성한다.
- WebSecurityEnablerConfiguration
- 스프링 시큐리티에서 이미지, CSS, JS와 같은 웹 리소스에 대한 보안 설정을 담당하는 WebSecurity 빈을 생성한다.
- SecurityDataConfiguration
- 스프링 시큐리티와 스프링 데이터를 연동하는 데 사용된다.
- SecurityEvaluationContextExtension 빈을 정의한다.
UserDetailsServiceAutoConfiguration
- 애플리케이션에 UserDetailsService 구현체가 빈으로 등록돼 있지 않으면 InMemoryUserDetailsManager를 빈으로 등록해준다.
- InMemoryUserDetailsManager에는 기본 계정 user가 포함되어 있다.
SecurityFilterAutoConfiguration
- DelegatingFilterProxyRegistrationBean 빈을 생성한다.
- DelegatingFilterProxyRegistrationBean은 DelegatingFilterProxy 필터를 생성하고 서블릿 컨테이너에 등록하는 역할을 담당하는 빈이다.
- SecurityAutoConfiguration 클래스가 설정된 다음에 설정된다.
책
'실전 스프링부트' 카테고리의 다른 글
[ch05-3] 스프링 시큐리티 적용 (0) | 2024.03.19 |
---|---|
[ch05-1] 스프링 시큐리티 소개 (0) | 2024.03.19 |
[ch03-5] @Query로 쿼리문 지정 (0) | 2024.03.12 |
[ch03-4] 스프링 데이터를 사용한 데이터 조회 (0) | 2024.03.11 |
[ch03-3] CrudRepository 인터페이스 이해 (0) | 2024.03.11 |