킴의 레포지토리
Spring Security의 인증과정과 ThreadLocalSecurityContextHolderStrategy 본문
1. ThreadLocal과 SecurityContext
1-1.ThreadLocal이란?
ThreadLocal은 java.lang 패키지에 속하는 클래로 특정 스레드와 관련된 상태를 저장하기 위해 사용된다. 클래스의 private static 필드로 사용되는 경우가 많다.
- thread는 메모리를 어떻게 공유하고 사용하나
- threadlocal은 왜사용하는가
- threadlocal 사용시 주의할점은
Spring Security에서 ThreadLocal을 사용하는 이유
Spring Security는 기본적으로 ThredLocal을 사용하여 SecurityContext를 저장한다. 아래는 SpringSecurity에서 인증 정보를 저장하기 위해 사용하는 SecurityContextHolder클래스이다. 1.에서 확인할 수 있듯이 시스템 환경 변수에 spring.security.strategy에 해당하는 값이 없으면 ThreadLocal 모드로 동작한다. 1. ThreadLocal 모드는 ThreadLocalSecurityContextHolderStrategy를 사용한다.
3.에서 확인할 수 있듯이ThreadLocalSecurityContextHolderStrategy는 ThreadLocal을 사용하여 SecurityContext를 저장한다.
Spring Security가 Security Context는 ThreadLocal 타입으로 저장하는 이유는 Security Context에 다음과 같은 사항이 요구되기 때문이다.
- 스레드별 컨텍스트 분리: 각 HTTP 요청은 별도의 스레드에 의해 처리된다. SecurityContext는 각 요청의 인증정보를 담고 있기 때문에 각 스레드별로 다른 정보를 담아야하고 다른 스레드의 컨텍스트에 접근할 수 없어야한다. 즉, SecurityContext는 스레드별로 독립된 공간에서 관리되어야한다.
- 접근의 용이성: 요청 처리 동안 여러 클래스에서 SecurityContext에 접근해서 인증 정보를 얻어올 수 있어야 한다.
- 요청 후 정리: 요청 처리가 끝난 후 스레드는 스레드풀로 반환되고 다른 요청 처리를 위해 재사용된다. 따라서, 요청이 끝날 때 보안 컨텍스트를 쉽게 지울 수 있어야 한다.
SecurityContext를 ThreadLocal 타입으로 관리하면 각 스레드별로 독립된 컨텍스트에서 인증 정보를 다룰 수 있게 되어 다른 스레드로부터 접근될 위험이 없어지고 동시성 위험이 없어진다. 따라서, 민감 정보지만 여러 클래스에서 쉽게 접근해 인증 정보를 불러올 수 있고, 요청 처리가 끝났을때 쉽게 인증 정보를 제거할 수 있게 된다.
따라서, 인증을 담당하는 필터에서 인증이 완료되면 *SecurityContextHolder.getContext().setAuthentication()*으로 요청의 인증 정보를 저장한 후 인터셉터나 컨트롤러, 서비스 레이어 어디서든 요청의 인증 정보를 불러올 수 있게 된다. 또한, 요청 처리가 다 끝나고 스레드가 스레드 풀에 반납되기 직전에 FilterChainProxy에서 securityContextHolder.clearContext()로 인증 정보를 삭제해서 스레드가 재사용될때 다른 요청의 인증 정보를 가지지 않도록 할 수 있다.
참고로 GlobalSecurityContexHolderStrategy는 Security Context를 정적 변수로 관리한다. 여러 클래스에서 쉽게 인증 정보에 접근이 가능하지만, 여러 스레드에서 접근할 수 있게 되어 동시성 문제 및 보안 정보 유출 문제 등이 발생할 수 있다
'study > java' 카테고리의 다른 글
JAVA: 익명 객체와 람다식 그리고 헷갈리는 스트림 문법 정리 (0) | 2024.04.23 |
---|---|
좋은 설계를 위한 OOP와 SOLID 원칙 적용 (0) | 2024.04.08 |