Spring Security에서는 인증과 인가를 구분해 처리해주고 있는데요, 이번 포스팅에서는 인증 관련 아키텍쳐를 알아보도록하겠습니다.
처음 접하시는 분이라면 인증과 인가가 무엇인지, 어떤 차이가 있는지 모르실텐데요. 이 둘의 차이는 아래와 같습니다.
인증(Authentication)
- 사용자가 누구인지 확인하는 절차
- 예) 사용자가 카페 회원인지 확인
인가(Authorization)
- 사용자가 요청을 실행할 수 있는 권한이 있는지 확인하는 절차
- 예) 사용자가 카페 게시판에 게시글을 작성할 수 있는 등급인지 확인
혹시 Spring Security의 필터 기반 동작 방식 혹은 DelegatingFilterProxy와 FilterChainProxy를 모르신다면?
이전 포스팅을 먼저 보시길 바랍니다!
Authentication
Authentication은 사용자의 인증 정보를 저장하는 토큰입니다.
인증 시에는 아이디와 패스워드를 담고 인증 절차를 위해 전달되고, 인증 후에는 최종 인증 결과를 담고 SecurityContext에 저장되어 전역적으로 참조할 수 있게됩니다.
Authentication은 아래와 같은 구조를 가지고있습니다.
- principal : 사용자 아이디 혹은 User 객체
- credentials : 사용자 비밀번호
- authorities : 인증된 사용자의 권한 목록
- details : 인증 부가 정보
- authenticated : 인증 여부
SecurityContext
Authentication 객체가 저장되는 보관소로, ThreadLocal에 저장되어 어디서든 참조가 가능합니다.
인증이 완료되면 HttpSession에 저장되어 애플리케이션 전반에 걸쳐 참조가 가능합니다.
SecurityContextHolder
SecurityContext를 저장하고 관리합니다. 아래 세가지 전략을 제공하며, SecurityContextHolder를 통해 SecurityContext를 참조할 수 있습니다.
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
MODE_THREADLOCAL
- 기본값
- ThreadLocal을 사용해 쓰레드당 SecurityContext 객체를 할당해 같은 쓰레드 내에서 공유 가능합니다.
MODE_INHERITABLETHREADLOCAL
- InheritableThreadLocal을 사용해 메인 쓰레드와 자식 쓰레드간의 SecurityContext 공유를 허용합니다.
MODE_GLOBAL
- 애플리케이션에서 단 하나의 SecurityContext를 저장합니다.
- JVM 내의 인스턴스들은 모두 SecurityContext를 공유할 수 있습니다.
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override protected void configure(HttpSecurity http) throws Exception {
SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
}
}
SecurityContextPersistenceFilter
SecurityContext 객체를 생성하고 저장하고 조회합니다.
익명 사용자 🔵
- 새로운 SecurityContext 객체를 생성하여 SecurityContextHolder에 저장합니다.
- AnonymousAuthenticationFilter 에서 AnonymousAuthenticationToken 객체를 SecurityContext에 저장합니다.
인증 시 🟣
- 새로운 SecurityContext 객체를 생성하여 SecurityContextHolder에 저장합니다.
- UsernamePasswordAuthenticationFilter에서 인증 성공 후 SecurityContext에 UsernamePasswordAuthentication 객체를 저장합니다.
- 인증이 최종 완료되면 Session에 SecurityContext를 저장합니다.
인증 후 🔴
- Session에서 SecurityContext를 꺼내어 SecurityContextHolder에 저장합니다.
- SecurityContext 안에 Authentication 객체가 존재하면 계속 인증을 유지합니다.
최종 응답 시 공통
- SecurityContextHolder.clearContext()
Authentication Flow
- Form Login 요청
- UsernamePasswordAuthenticationFilter 에서 인증 전 토큰 객체를 생성합니다.
- AuthenticationManager에서 적절한 AuthenticationProvider에 인증을 위임합니다.
- AuthenticationProvider에서 구현체를 통해 User 객체를 조회해 UserDetails 타입으로 얻어옵니다.
- AuthenticationProvider에서 UserDetails와 권한 정보를 담은 인증 후 토큰 객체를 생성해 AuthenticationManager로 전달합니다.
- UsernamePasswordAuthenticationFilter로 Authentication 객체가 전달되고, SecurityContext에 인증 객체를 저장한 뒤 응답합니다.
Reference
'🌱 SPRING' 카테고리의 다른 글
[Spring Security] 스프링 시큐리티 주요 아키텍쳐 3 - 인가(Authorization) (0) | 2021.12.16 |
---|---|
[Spring Security] 스프링 시큐리티 주요 아키텍쳐 1 - DelegatingFilterProxy, FilterChainProxy (0) | 2021.12.06 |
[Spring Cloud Config] 설정값을 외부에서 관리하자! - 실습 (4) | 2021.10.10 |
[Spring Cloud Config] 설정값을 외부에서 관리하자! - 기본 (0) | 2021.10.10 |
[SpringCloud] Resilience4j와 Spring Cloud Circuit Breaker (0) | 2021.05.16 |