[ODOP] 84일차 - 인증 저장소(SecurityContext, *Holder)
![[ODOP] 84일차 - 인증 저장소(SecurityContext, *Holder)](/content/images/size/w1200/2023/08/-----2023-08-01----10.29.26-18.png)
SecurityContext
SecurityContext 안의 Authentication 이 존재하고 그 안에 User 객체가 존재한다
- Authentication 객체가 저장되는 보관소로 필요 시 언제든 Authentication 객체를 꺼내어 쓸 수 있도록 제공되는 클래스
- ThreadLocal 에 저장되어 아무 곳에서나 참조가 가능하도록 설계함
- 인증이 완료되면 HttpSession 에 저장되어 어플리케이션 전반에 걸쳐 전역적인 참조가 가능하다
SecurityContextHolder
SecurityContext 객체 저장 방식
- MODE_THREADLOCAL
스래드당 SecurityContext 를 할당, 기본값 - MODE_INHERITABLETHREADLOCAL
메인 스레드와 자식 스레드에 관하여 동일한 SecurityContext 를 유지 - MODE_GLOBAL
응용 프로그램에서 단 하나의 SecurityContext 를 저장한다
SecurityContext 를 static 으로 선언하여 모든 Thread 에서 접근할 수 있도록 하는 것
SecurityContextHolder.clearContext()
SecurityContext 기존 정보 초기화
만약 사용자의 인증 데이터가 필요하다면 어떤 함수에서든 다음의 구문을 통해 사용자의 인증 정보를 다룰 수 있다
Authentication authentication = SecurityContextHolder.getContext().getAuthentication()
이미 로그인 되어있는 사용자라면 다음과 같이 Controller 에서도 인증 정보를 가져올 수 있다
...
@Controller
public String loginUser(HttpSession session) {
SecurityContext context = (SecurityContext) session.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
Authentication authentication = context.getAuthentication();
return "home";
}
...
자식 Thread 에서도 SecurityContextHolder 접근할 수 있게 만들기
SecurityContext 를 자식 스래드에게도 공유하는 방법
다음 설정을 추가해주면 적용할 수 있다.
`SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);`
...
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
...
SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
}
}
그 외의 설정으로는 default 인 MODE_THREADLOCAL 을 제외하고 MODE_GLOBAL 이 존재하는데, 이역시 다른 스래드에 Context 를 공유할 수 있다