반응형
SecurityContextHolder란?
- 기본적으로 ThreadLocal을 사용
- 한 쓰레드 내에서 사용하는 공용 저장소
- 쓰레드 내에서 Application을 공유 할수있다.
- SecurityContextHolder를 사용
- 쓰레드가 달라지면 제대로 된 인증 정보를 가져올 수 없음
- SecurityContextHodler는 싱글톤 객체
- SecurityContextHolder가 로드 될 때 한번 호출됩니다
static { initialize(); }
- SecurityContextHolder가 로드 될 때 한번 호출됩니다
- 해당 initialize 메소드에서 SecucirtyContextHolder에 대한 전략 방식을 파악
private static void initialize() {
if (!StringUtils.hasText(strategyName)) {
strategyName = "MODE_THREADLOCAL";
}
if (strategyName.equals("MODE_THREADLOCAL")) {
strategy = new ThreadLocalSecurityContextHolderStrategy();
} else if (strategyName.equals("MODE_INHERITABLETHREADLOCAL")) {
strategy = new InheritableThreadLocalSecurityContextHolderStrategy();
} else if (strategyName.equals("MODE_GLOBAL")) {
strategy = new GlobalSecurityContextHolderStrategy();
} else {
try {
Class<?> clazz = Class.forName(strategyName);
Constructor<?> customStrategy = clazz.getConstructor();
strategy = (SecurityContextHolderStrategy)customStrategy.newInstance();
} catch (Exception var2) {
ReflectionUtils.handleReflectionException(var2);
}
}
++initializeCount;
}
- MODE_THERADLOCAL - 쓰레드별로 SecurityContext 관리
- MODE_INHERITABLETHREADLOCAL - 상위 쓰레드에서 하위 쓰레드로 Context 정보를 상속해줌
- MODE_GLOBAL - SecurityContext를 쓰레드 공용으로 관리
- SecurityContext 특성 상 Principal에 사용자 인증저보를 담고있으므로,
보안 이슈가 있을 수 있음 - 성능저하
- JVM에서 제공하는 모든 스레드에서 같은 SecurityContext를 요구할때 사용
Ex) Java Swing
- SecurityContext 특성 상 Principal에 사용자 인증저보를 담고있으므로,
의문점
- 왜 SecurityContext의 DeafultMode는 ThreadLocal인가?
- 사용자 정보가 담겨있는 주체이므로, 보안 상의 이유
- 성능 상 필요 없는 정보를 담고 있을 경우 느려질 수 있음
- 각 쓰레드별로 SecurityContext를 가져간다면 쓰레드 별 SecurityContext의 정확성 보장이 되는가?
- SecurityContext는 단순히 유저 인증정보를 담고있는 객체이므로, 관련 기능은 지원하지 않으며, 특수한 경우 추가 기능개발이 필요합니다.
- 이전에 로그인하여 SecurityContext의 사용자 계정이 로드되어 있다면, 어드민 계정에 의해
권한이 변경되거나, 탈퇴처리 진행될 경우- 위 사항과 동일한 부분이며, 즉각적인 처리가 필요한 사항이라면 관련 동기화 작업이 필요
- 쓰레드별로 SecurityContext가 관리된다면, 해당 유저가 어떤 쓰레드의 SecurityContext에서 관리되는지 어떻게 판단하는가
- 결론적으로는 SecurityContext의 역할이 아니다.
- Security 환경에서 Session을 사용할경우
- SecurityContext에서 인증 정보를 가져와서 Principal 객체를 추출합니다
Authentication는 Principal 인터페이스 객체를 상속 받은 인터페이스입니다.
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
해당 소스만 보았을 땐 이해가 어렵다.
클라이언트 요청에 알맞는 유저정보를 가져오는 법
- SecurityFilter에서 해당 Url 처리를 인터셉트함. (권한이 없을경우)
- 클라이언트 쿠키에 저장되어 있는 (예를들어 JSESSION) 값을 가져온 후 HttpServletRequest를 통해 해당 Session 키 값에 알맞는 HttpSession 반환
HttpSession session = request.getSession(false);
SecurityContext securityContext = (SecurityContext) session.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
Authentication authentication = securityContext.getAuthentication();
- 위의 작업으로 인해 request.getSession(false)메소드 호출하였을때도 알맞는 HttpSession을 반환받을수 있음
- 이 부분은 세션 하이재킹 등 보안적 이슈로 직접적으로 인자 값을 넘기지 않음
- 해당 HttpSession에 저장되어 있는 SecurityContext를 반환받아, Authtication 객체를 가져올수있음.
위의 한줄짜리 Authentication에서 SecurityContextHolder.getContext()메소드 까지 호출되었을때 HttpSession에서 해당 SecurityContext를 가져온다는데, 나중에 확인 필요
반응형
'Java' 카테고리의 다른 글
[Spring]PageRequest이용한 페이징처리 (0) | 2023.08.15 |
---|---|
[QueryDSL]Q Class Import 불가 (0) | 2023.06.02 |
[SpringBoot]SpringBoot 3.x.x War 배포에러 (0) | 2023.03.01 |
SpringFramework 사용이유 및 장단점 (0) | 2022.12.14 |
[Spring]인텔리제이 환경 Devtools 미작동 시 확인사항 (0) | 2022.10.14 |