시큐리티 인증 / 인가 흐름도
- SecurityContext
Authentication 저장 | 현재 인증된 사용자의 Authentication 객체를 저장 |
ThreadLocal 저장소 사용 | SecurityContextHolder 를 통해 접근되며 ThreadLocal 저장소를 사용해 각 스레드가 자신만의 보안 컨텍스트를 유지 클라이언트마다 스레드 생성 → 스레드마다 로컬 저장소 존재 → 로컬 저장소에 시큐리티 컨텍스트 저장 ⇒ 각 스레드마다 독립적인 컨텍스트 객체를 가짐 *스레드마다 독립적인 컨텍스트를 가지기 때문에 다른 스레드의 컨텍스트에 접근할 수 없어 자신만의 보안 컨텍스트가 유지 된다는 것 |
애플리케이션 전반에 걸친 접근성 | 애플리케이션의 어느 곳에서나 접근 가능하며 현재 사용자의 인증 상태나 권한을 확인하는 데 사용 |
- SecurityContextHolder
SecurityContext 저장 | 현재 인증된 사용자의 Authentication 객체를 담고 있는 SecurityContext 객체를 저장 |
전략 패턴 사용 | 다양한 저장 전략을 지원하기 위해 SecurityContextHolderStrategy 인터페이스를 사용 |
기본 전략 | MODE_THREADLOCAL |
전략 모드 직접 지정 | SecurityContextHolder.setStrategyName(String) |
- SecurityContextHolder 저장 모드
MODE_THREADLOCAL | 기본 모드로, 각 스레드가 독립적인 보안 컨텍스트를 가짐 → 대부분의 서버 환경에 적합 |
MODE_INHERITABLETHREADLOCAL | 부모 스레드로부터 자식 스레드로 보안 컨텍스트가 상속되며 작업을 스레드 간 분산 실행하는 경우 유용할 수 있음 |
MODE_GLOBAL | 전역적으로 단일 보안 컨텍스트를 사용하며 서버 환경에서는 부적합하며 주로 간단한 애플리케이션에 적합 |
구조
- clearContext() : 현재 컨텍스트 삭제
- getContext() : 현재 컨텍스트 반환
- getDeferredContext() : 현재 컨텍스트를 반환하는 Supplier 반환
- setContext(SecurityContext context) : 현재 컨텍스트를 저장
- setDeferredContext(Supplier<SecurityContext> deferredContext) : 현재 컨텍스트를 반환하는 Supplier 를 저장
- createEmptyContext() : 새롭고 비어 있는 컨텍스트를 생성
SecurityContext 참조 및 삭제
- 참조 - SecurityContexHolder.getContextHolderStrategy().getContext()
- 삭제 - SecurityContexHolder.getContextHolderStrategy().clearContext()
SecurityContextHolder & SecurityContext 구조
- 스레드마다 할당 되는 전용 저장소에 SecurityContext 를 저장하기 때문에 동시성의 문제가 없음
- 스레드 풀에서 운용되는 스레드일 경우 새로운 요청이더라도 기존의 ThreadLocal이 재사용될 수 있기 때문에 클라이언트로 응답 직전에 항상 SecurityContext를 삭제
- 클라이언트1의 할당이 끝나고 새로운 클라이언트4가 할당이 되었을 때, ThreadLocal1의 SecurityContext가 남아있으면, 클라이언트1의 인증 정보를 가지고 있게 됨
SecurityContextHolderStrategy 사용하기
- 기존 방식
- SecurityContextHolder를 통해 SecurityContext에 정적으로 접근할 때 여러 애플리케이션 컨텍스트가 SecurityContextHolderStrategy를 지정하려고 하는 경우 경쟁 조건을 만들 수 있음
SecurityContext context = SecurityContextHolder.createEmptyContext();
context.setAuthentication(authentication);
SecurityContextHolder.setContext(context);
- 변경 방식
- 애플리케이션이 SecurityContext를 정적으로 접근하는 대신 SecurityContextHolderStrategy 를 자동 주입이 될 수 있도록 함
- 각 애플리케이션 컨텍스트는 자신에게 가장 적합한 보안 전략을 사용 가능
SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder.getContextHolderStrategy();
SecurityContext context = securityContextHolderStrategy.createEmptyContext();
context.setAuthentication(authentication);
securityContextHolderStrategy.setContext(context);
정리
- SecurityContextHolder에는 여러 개의 TheradLocal이 있고, 각각의 ThreadLocal에는 SecurityContext를 가지고 있고, 각각의 SecurityContext에는 각각의 Authentication(인증 정보)가 저장되어 있음
→ 대표적으로 그려지는 그림은 SecurityContextHolder > SpringContext > Authentication - SecurityContextHolder에서 SecurityContext로 바로 접근하지 말고, SecurityContextHolder.getContextHolderStragtegy를 통해 접근하는 것을 습관화
'Language > Spring Security' 카테고리의 다른 글
인증 제공자 - AuthenticationProvider (0) | 2024.07.24 |
---|---|
인증 관리자 - AuthenticationManager (0) | 2024.07.24 |
인증 - Authentication (0) | 2024.07.16 |
요청 캐시 - RequestCache / SavedRequest (0) | 2024.07.16 |
로그 아웃 - logout() (0) | 2024.07.16 |