[데브코스] Spring Security - 2
Updated: Categories: TILW16D1 - ThreadLocal / SecurityContext / 인증과정에 대해 알아보자
Thread
- Spring에서의 WAS(Tomcat)은 ThreadPool을 생성한다. (기본으로 200개를 생성)
- 각 스레드는 한 요청을 맡아 작업이 끝날때까지 다른 요청을 받지 않음.
- 요청이 끝나면 스레드를 반납한다.
ThreadLocal
final static ThreadLocal<타입> threadLocalValue = new ThreadLocal<>();
- 하나의 스레드에서 전역적으로 공유 가능한 변수를 가질 수 있다.
- 동일 스레드내에서는 어떤 계층에서든지
ThreadLocal
변수에 접근할 수 있다. - 하지만 서로 다른 스레드는 서로의 로컬 변수를 참조할 수 없다.
- 하나의 요청을 맡은 스레드의 작업이 끝날때 반드시 로컬 변수는 clear해야 한다.
- 다음 요청시 해당 스레드에 변수가 남아있다면 로직 오류가 발생할 수 있기 때문
SecurityContext
Authentication
- 사용자를 표현하는 인증 토큰 인터페이스.
- 토큰(구현체) 종류는 다음과 같다.
AnonymousAuthenticationToken
: 익명 사용자를 표현UsernamePasswordAuthenticationToken
: 로그인한 사용자를 표현RememberMeAuthenticationToken
: remember-me로 로그인된 사용자 표현
- 내부에는 다음과 같은 정보를 가진다.
Principal
: 인증여부에 따라 값이 달라짐. 보통 인증 후에 User 객체 저장Credentials
: 비밀번호 등Authorities
: 권한 리스트
SecurityContext
- Spring Security는
SecurityContext
를 사용해 인증정보를 관리한다. SecurityContext
는ThreadLocal
변수에 담겨 1 요청 == 1 스레드 내에서 공유된다.SecurityContext
자체는 특별한 기능 없이Authentication
객체를 Wrapping 해주는 역할임
ThreadLocalSecurityContextHolderStrategy class
private static final ThreadLocal<SecurityContext> contextHolder = new ThreadLocal();
SecurityContextHolder
SecurityContextHolder
에서는 해당SecurityContext
에 접근하여 조작해주는 역할을 함- SecurityContext get, set, clear 등등…
FilterChainProxy
를 살펴보면 finally 블록에서SecurityContextHolder.clearContext()
메소드를 호출한다.- Thread가 ThreadPool에 반환되기전 ThreadLocal 변수 값을 제거하기 위함
DefaultLoginPageGeneratingFilter
- 로그인 페이지 html을 렌더링해주는 필터
DefaultLoginPageGeneratingFilter class
- 기본 로그인 페이지 html을 이 클래스에서 생성하고 있음을 확인할 수 있음
- 물론 로그인 페이지나 id/password parameter를 커스텀할 수 있다.
http.formLogin()
.loginPage(커스텀URL)
.usernameParameter()
.passwordParameter()
Authentication
- Spring Security에서 아이디/비밀번호를 사용한 인증절차는 아래와 같은 구조를 가진다.
로그인 인증
- 어떤 사용자가 로그인을 시도했다고 가정했을 때, 아래와 같은 클래스들이 사용된다.
- 파란색은 인터페이스, 회색은 구현체이다.
AbstractAuthenticationProcessingFilter
: 사용자 인증을 위한 토큰(Authentication
객체)를 생성함UsernamePasswordAuthenticationToken
을 생성- 여기서 권한 리스트
authorities
는 null이다.
AuthenticationManager
: 사용자 인증을 위한 Provider 리스트를 관리한다.AuthenticationManager
의 default 구현체는ProviderManager
- 실제 인증을 처리할 Provider는 토큰(
Authentication
객체) 종류에 따라 결정된다. UsernamePasswordAuthenticationToken
일 경우DaoAuthenticationProvider
가 선택된다.
AuthenticationProvider
: 실제 인증 로직을 처리하고, 최종 토큰을 생성한다.- 권한 리스트
authorities
를 담는다
- 권한 리스트
RememberMe 인증
- RememberMe를 체크하고 로그인한 사용자가 나중에 다시 로그인할 경우
- 쿠키를 파싱하여 정보를 받아온다.
- 인증이 될때마다 토큰을 새로 생성한다.
.rememberMe()
.key(키값)
.tokenValiditySeconds(쿠키수명)
.rememberMeParameter(파라미터이름)
.rememberMeCookieName(쿠키이름)
.alwaysRemember(bool값) // 활성화 여부
- 여러 쿠키 설정을 커스텀할 수 있다.