SecurityContext
-
Authentication 의 보관소, 언제든 Authentication을 꺼내 사용할 수 있도록 제공되는 클래스이다.
-
ThreadLocal 에 저장되어 아무 곳에서 참조가 가능하도록 설계됨
-
ThreadLocal 은 Thread 하나에 할당 된 저장소이다. 즉 Thread-Safe 하다.
-
ThreadLocal은 인증 완료시 HttpSession 저장되어 Application 전반에서 참조가 가능하다.
SecurityContextHolder
SecurityContext를 감싸 저장하는 객체, 저장방법은 3가지이다.
-
MODE_THREADLOCAL : 하나의 스레드 당 SecurityContext 를 할당 , default 값
-
MODE_INHERITABLETHREADLOCAL : 부모 스레드와 자식 스레드에 관해 동일한 SecurityContext를 유지함, 즉 프로세스 안에서 쓰레드의 자식쓰레드에게도 SecurityContext 가 공유 됨
-
MODE_GLOBAL : 응용 프로그램에서 단 하나의 SecurityContext를 저장함
-
SecurityContextHolder.clearContext() : SecurityContext 정보를 초기화한다.
-
Authentication auth = SecurityContextHolder.getContext().getAuthentication()
동작 구조
-
사용자가 인증을 시도
-
Server 에서 Request에 대한 고유의 Thread 가 만들어지고 Thread 에 대한 TreadLocal(전역저장소) 가 생성
-
UsernamePasswordAuthenticationFilter 작동
-
실패시 SecurityContextHolder.clearContext()
-
성공시 UsernamePasswordAuthenticationFilter가 최종 Authentication 객체를 SecurityContextHolder에 담긴 ThreadLocal에 있는 SecurityContext에 담음
-
HttpSession에 "SPRING_SECURITY_CONTEXT"라는 이름으로 SecurityContext 를 저장
- SecurityContextHolder > ThreadLocal > SecurityContext > Authentication
ThreadLocal 생성전략 설정의 차이점
ThreadLocal 생성전략은 기술 된 3가지
-
MODE_THREADLOCAL
-
MODE_INHERITABLETHREADLOCAL
-
MODE_GLOBAL
default 인 MODE_THREADLOCAL 의 경우에, 해당 컨트롤러의 Authentication 값은 null 이다.
@GetMapping(value = "/thread")
public String thread(){
new Thread(
new Runnable() {
@Override
public void run() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
//자식 쓰레드에서 확인해보자
}
}
).start();
return "thread";
}
ThreadLocal 생성 전략 변경
SecurityContextHolder.setStrategyName(원하는 ThreadLocal 생성전략)
여기서는 SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL) 이겠다.
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest()
.authenticated();
http
.formLogin();
SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
}
}
이렇게 설정하고 디버깅을 해보면 자식 스레드 에서도 SecurityContext 값이 공유되는 것을 볼 수 있다.
'springframework > 시작하자SpringSecurity' 카테고리의 다른 글
19.Authentication Flow (0) | 2020.09.22 |
---|---|
18.인증 저장소 필터 , SecurityContextPersistenceFilter (0) | 2020.09.22 |
16.Authentication (0) | 2020.09.21 |
15.필터 초기화와 다중 보안 설정 (0) | 2020.09.21 |
14.DelegatingFilterProxy, FilterChainProxy (0) | 2020.09.21 |