킴의 레포지토리

Spring Security의 인증과정과 ThreadLocalSecurityContextHolderStrategy 본문

study/java

Spring Security의 인증과정과 ThreadLocalSecurityContextHolderStrategy

킴벌리- 2024. 5. 14. 11:11

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에 다음과 같은 사항이 요구되기 때문이다.

  1. 스레드별 컨텍스트 분리: 각 HTTP 요청은 별도의 스레드에 의해 처리된다. SecurityContext는 각 요청의 인증정보를 담고 있기 때문에 각 스레드별로 다른 정보를 담아야하고 다른 스레드의 컨텍스트에 접근할 수 없어야한다. 즉, SecurityContext는 스레드별로 독립된 공간에서 관리되어야한다.
  2. 접근의 용이성: 요청 처리 동안 여러 클래스에서 SecurityContext에 접근해서 인증 정보를 얻어올 수 있어야 한다.
  3. 요청 후 정리: 요청 처리가 끝난 후 스레드는 스레드풀로 반환되고 다른 요청 처리를 위해 재사용된다. 따라서, 요청이 끝날 때 보안 컨텍스트를 쉽게 지울 수 있어야 한다.

SecurityContext를 ThreadLocal 타입으로 관리하면 각 스레드별로 독립된 컨텍스트에서 인증 정보를 다룰 수 있게 되어 다른 스레드로부터 접근될 위험이 없어지고 동시성 위험이 없어진다. 따라서, 민감 정보지만 여러 클래스에서 쉽게 접근해 인증 정보를 불러올 수 있고, 요청 처리가 끝났을때 쉽게 인증 정보를 제거할 수 있게 된다.

따라서, 인증을 담당하는 필터에서 인증이 완료되면 *SecurityContextHolder.getContext().setAuthentication()*으로 요청의 인증 정보를 저장한 후 인터셉터나 컨트롤러, 서비스 레이어 어디서든 요청의 인증 정보를 불러올 수 있게 된다. 또한, 요청 처리가 다 끝나고 스레드가 스레드 풀에 반납되기 직전에 FilterChainProxy에서 securityContextHolder.clearContext()로 인증 정보를 삭제해서 스레드가 재사용될때 다른 요청의 인증 정보를 가지지 않도록 할 수 있다.

참고로 GlobalSecurityContexHolderStrategy는 Security Context를 정적 변수로 관리한다. 여러 클래스에서 쉽게 인증 정보에 접근이 가능하지만, 여러 스레드에서 접근할 수 있게 되어 동시성 문제 및 보안 정보 유출 문제 등이 발생할 수 있다