티스토리 뷰

반응형

Spring Security를 사용하다 보면 인증된 사용자 정보를 조회할 때 SecurityContextHolder.getContext().getAuthentication()을 자주 사용한다.
하지만 이 SecurityContext가 Thread-safe 하지 않기 때문에

Spring Security의 내부 동작 원리를 바탕으로 알아보고 멀티스레드 환경 또는 비동기 작업시 어떻게 관리하는지 알아보자.

 

1. SecurityContext란?

Spring Security에서 인증(Authentication) 및 권한(Authorization) 정보를 담고 있는 컨테이너

간단히 말해, 로그인한 사용자의 정보를 담고 있는 Thread-local 저장소다.

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
 

여기서 SecurityContextHolder는 현재 실행 중인 쓰레드에 바인딩된 인증 정보를 반환한다.

 


2. SecurityContext가 Thread-safe하지 않은 이유

Spring Security는 기본적으로 ThreadLocal 을 통해 SecurityContext를 관리한다.

private static final ThreadLocal<SecurityContext> contextHolder = new ThreadLocal<>();

즉, SecurityContext는 현재 실행 중인 쓰레드에만 바인딩된다.

 

❗문제상황

멀티 스레드 환경 혹은 비동기 작업 시에 다음과 같은 문제가 발생한다.

new Thread(() -> {
    Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    System.out.println(auth); // null
}).start();
  • 새 쓰레드는 SecurityContext를 상속받지 않기 때문에 getAuthentication()의 결과가 null이다.
  • 즉, 기존 쓰레드에서 설정한 인증 정보는 새로운 쓰레드에서 접근할 수 없다.
@RestController
public class AsyncController {

    @GetMapping("/async")
    public String asyncExample() {
        new Thread(() -> {
            Authentication auth = SecurityContextHolder.getContext().getAuthentication();
            System.out.println("Authentication: " + auth);
        }).start();

        return "Check console log";
    }
}

위와 같은 비동기 쓰레드에서는 인증 정보를 찾을 수 없기 때문에 null이 출력된다.

 


그럼 어떻게 해결할 수 있을까? 

1. DelegatingSecurityContextExecutor를 사용한다.

@EnableAsync
@Configuration
public class AsyncConfig implements AsyncConfigurer {

    @Override
    public Executor getAsyncExecutor() {
        return new DelegatingSecurityContextExecutor(Executors.newCachedThreadPool());
    }
}

 

2. SecurityContext를 수동으로 전파한다.

SecurityContext context = SecurityContextHolder.getContext();

new Thread(() -> {
    SecurityContextHolder.setContext(context);
    // 이후 작업
}).start();

 


참고 : https://www.baeldung.com/spring-security-async-principal-propagation

반응형