SecurityContext
- Authentication 객체가 저장되는 보관소로 필요시 언제든지 Authentication 객체를 꺼내어 쓸 수 있도록 제공되는 클래스
- Threadlocal에 저장되어 아무곳에서나 참조가 가능하도록 설계함
- 인증이 완료되면 HttpSession에 저장되어 어플리케이션 전반에 걸쳐 전역적인 참조가 가능하다
Threadlocal : 스레드마다 고유하게 할당되는 저장소가 있는데 스레드와 스레드가 공유되지 않고 각 할당된 저장소에게만
공유가 된다.
SecurityContextHolder
- SecurityContext 객체 저장 방식
- Mode_THREADLOCAL: 스레드당 SecurityContext 객체를 할당, 기본값
- Mode_INHERITABLETHREADLOCAL: 메인 스레드와 자식스레드에 관하여 동일한 SecurityContext를 유지
- Mode_GLOBAL: 응용 프로그램에서 단 하나의 SecurityContext를 저장한다
Mode_INHERITABLETHREADLOCAL:
메인스레드 안에 별도의 스레드를 만들게 되면 메인스레드도 자신만의 스레드로컬이 있듯이 자식 스레드도자신만의 스레드로컬이 있다. 이렇게 되면 각각의 스레드가 존재함으로써 데이터 공유가 되지 않는다 기본적으로는 메인스레드에다가SecurityContext를 저장한다 하지만 자식스레드에서 SecurityContext가 저장되어 있지 않기 때문에 Mode_INHERITABLETHREADLOCAL를 사용하여 자식스레드가 동일한SecurityContext를 참조할수 있게 한다.
Mode_GLOBAL:
static으로 변수를 선언해서 SecurityContext를 스테틱 변수에 저장하게 된다. static 메모리 에서 단하나만 유지가 되는 특징이 있다
- SecurityContextHolder.clearContext(): SecurityContext기존 정보 초기화
- Authentication authentication = SecurityContextHolder.getContext().getAuthentication() // 장소 상관없이 인증객체를 참조할수있다.
서버에서는 로그인요청을 받고 하나의 요청을 받는 스레드를 생성한다 ThreadLocal(전역저장소)는 스레드마다 할당이 된다.
이후에 스레드가 인증처리를 하게되고 사용자의 이름과 비밀번호를 담는 Authentication(인증객체)를 생성한다
만약에 인증에 실패 하게 된다면 SecurityContextHolder.clearContext()객체를 null로 초기화 해버린다.
성공하게되면 인증필터가 SecurityContextHolder안에 인증에 성공한 결과와 권한정보를 담기위해 Authentication(인증객체)생성하고 저장한다.
SecurityContextHolder 클래스를 보면 3가지의 전략을 확인할수 있다 기본값은 MODE_THREADLOCAL 이다 필자는 기본값으로 일단 해보기로 했다.
ThreadLocal<SecurityContext>를 보면 ThreadLocal를 선언하고 있고 getContext 메소드를 보면 get과 set으로
저장하고 꺼내올수 있다. SecurityContext는 인터페이스고 구현체는 SecurityContextImpl이다 여기구현체에도 get과 set으로 구현되어 있다.
필자는 메인 쓰레드와 자식 쓰레드간에 데이터가 공유되는지 확인하기 위해서 컨트롤을 이용했다.
getAuthentication으로 인증결과를 담은 인증객체 혹은 토큰를 가져 오고 session에 저장된 SecurityContext도 참조가 가능하기 때문에 확인해볼것이다. session에서 인증객체를 가져올때는 해당키로 찾아올건데 저장할때 키값은 "SpringSecurityContext"로 저장되어진다
그리고 하나의 스레드를 따로 만들었다
Runnable로 익명클래스를 만들어 객체를 생성했다. 똑같이 getAuthentication으로 메인스레드에 저장된 SecurityContext를 참조가 가능한지 확인해보기 위함이다.
필자는 user로 로그인했고 인증을 성공하였다 그러면 Authentication을 확인해보면 인증결과와 권한정보를 를 담은 객체를 확인할수가 있다. 그리고 session도 확인을 해보면 같은 객체가 확인할수 있다.
그리고 스레드를 확인해보면 null이다 즉 첫번째 전략으로는 스레드가 SecurityContext를 참조하지 못하는걸 확인할수 있다.
자 그러면 두번째 전략으로 SecurityContext를 참조해보자 !
자! 두번째 전략으로는 별도로 만들어진 스레드도 SecurityContext를 참조할수 있다!
'SpringSecurity' 카테고리의 다른 글
SpringSecurity(AuthenticationFlow) (0) | 2020.11.05 |
---|---|
SpringSecurity(SecurityContextPersistenceFilter) (0) | 2020.11.05 |
SpringSecurity(Authentication) (0) | 2020.11.05 |
SpringSecurity(필터초기화 다중보안설정) (0) | 2020.11.04 |
SpringSecurity(위임필터 초기화) (0) | 2020.11.03 |