본 글은 Spring Security docs 와 여러 블로그 들을 참고하고, 공부하면서 요약하였습니다.
1. SecurityContextHolder, SecurityContext
1) SecurityContext
Authentication 객체가 저장되는 보관소로 필요 시 언제든지 Authentication 객체를 꺼내어 쓸 수 있도록 제공되는 클래스이다.
SecurityContext는 ThreadLocal에 저장되어 아무 곳에서나 참조가 가능하도록 설계된다.
인증이 완료되면 HttpSession에 저장되어 어플리케이션 전반에 걸쳐 전역적인 참조가 가능하다.
이때 ThreadLocal은 각 Thread별로 할당된 별도의 공간이다. 따라서 공유되지 않으며, 다른 Thread로부터 공유되지 않는다.
2) SecurityContextHolder
SecurityContext 객체를 저장하고 감싸고 있는 wrapper 클래스이다.
SecurityContext객체를 저장하는 방식에는 3가지 MODE가 있다.
- MODE_THREADLOCAL: 각 스레드별로 SecurityContext객체를 할당. default 방식
- MODE_INHERITABLETHREADLOCAL: 메인 스레드와 자식 스레드에 관하여 동일한 SecurityContext를 유지
- MODE_GLOBAL: 응용 프로그램에서 단 하나의 SecurityContext를 저장한다.
SecurityContext 와 SecurityContextHolder를 사용하는 코드는 대략 다음과 같다.
SecurityContext context = SecurityContextHolder.createEmptyContext();
Authentication authentication = new TestingAuthenticationToken("username", "password", "ROLE_USER");
context.setAuthentication(authentication);
SecurityContextHolder.setContext(context);
비어있는 SecurityContext를 생성하고, 여기에 인증객체인 Authentication을 저장한다.
이 SecurityContext를 SecurityContextHolder에 저장하면 전역으로 사용이 가능하게 된다.
SecurityContextholder.clearContext()를 통해서 SecurityContext기본 정보를 초기화 시킬 수 있다.
또한 다음과 같이 인증객체를 어디서든 꺼내어 사용할 수 있다.
Authentication authentication = SecurityContextHolder.getContext().getAuthentication()
▶ Flow
1. Login을 사용자가 시도
2. Server가 요청을 받아서 Thread를 생성 (ThreadLocal 할당)
3. thread가 인증 처리 시도 → 인증 객체(Authentication) 생성
4. (인증 실패) SecurityContextHolder.clearContext() 인증객체 초기화
5. (인증 성공) SecurityContextHolder안의 SecurityContext에 인증객체(Authentication)저장
→ SecurityContextHolder에 필드로 ThreadLocal을 가지고 있다.
6. SecurityContext가 최종적으로는 "SPRING_SECURITY_CONTEXT"라는 이름으로 HttpSession에 저장이 된다.
2. 디버깅 해보기
▶ SecurityContextHolder
SecurityContextHolder는 처음에 다음 init 메서드를 호출하게 된다.
빨간 박스안을 보면 위에서 언급한 3가지 전략중 하나를 선택하게 된다.
이중에서 ThreadLocalSecurityContextHolderStrategy()가 default 방식이라 선택된다. (설정으로 변경 가능)
▶ ThreadLocalSecurityContextHolderStrategy
ThreadLocalSecurityContextHolderStrategy 클래스의 코드는 위와 같다.
내부에 필드로 contextHolder를 가지고 있다. 여기에 SecurityContext를 저장하게 된다.
또한 SecurityContext는 인터페이스 이다. 이를 구현한 구현체는 다음과 같다.
▶ SecurityContextImpl
내부에 Authentication 객체를 저장하게 됩니다.
참고
https://catsbi.oopy.io/f9b0d83c-4775-47da-9c81-2261851fe0d0
'BackEnd > Spring Security' 카테고리의 다른 글
[Spring Security] Authentication Flow (0) | 2022.08.27 |
---|---|
[Spring Security] SecurityContextPersistenceFilter (1) | 2022.08.27 |
[Spring Security] Authentication (0) | 2022.08.25 |
[Spring Security] 필터 초기화와 다중 보안 설정 (1) | 2022.08.25 |
[Spring Security] DelegatingFilterProxy, FilterChainProxy (0) | 2022.08.25 |
댓글