SecurityContext
- Authentication 객체가 저장되는 보관소로 필요 시 언제든지 Authentication 객체를 꺼내 쓸 수 있도록 제공되는 클래스
- Authentication 객체 안에는 User 객체가 저장되어 있다.
- ThreadLocal에 저장되어 아무곳에서나 참조가 가능하다.
- ThreadLocal? Thread마다 고유하게 할당되는 저장소
- 인증이 완료되면 HttpSession에 저장되어 어플리케이션 전반에 걸쳐 전역적인 참조가 가능하다.
SecurityContextHolder
- SecurityContext 객체를 감싸고 있는 클래스이다.
- SecurityContext 객체 저장 방식
- MODE_THREADLOCAL : 스레드당 SecurityContext 객체를 할당 (default)
- MODE_INHERITABLETHREADLOCAL : 메인 스레드와 자식 스레드에 관하여 동일한 SecurityContext를 유지
- 언제 사용? Async한 개발 진행 시 SecurityContext 공유를 위해서 사용한다.
- MODE_GLOBAL : 응용 프로그램에서 단 하나의 SecurityContext를 저장한다.
- 언제 사용? StandAlone 어플리케이션 개발시 사용한다.
- SecurityContextHolder.clearContext() : SecurityContext 기존 정보 초기화한다.
- ThreadLocal 스레드 전역저장소를 가지고 있고, ThreadLocal 전역 저장소에 SecurityContext 객체가 저장되게 된다.
@RestController
public class SecurityController {
@GetMapping("/")
public String index(HttpSession session) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
SecurityContext context = (SecurityContext)session.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
Authentication authentication2 = context.getAuthentication();
return "home";
}
@GetMapping("/thread")
public String thread() {
new Thread(new Runnable() {
@Override
public void run() {
// 메인 Thread와 자식 Thread간에 SecurityContext를 공유 할 수 없다.
// 따라서 null을 리턴한다.
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
}
}.start();
return "thread";
}