2022년 5월 18일 TIL

yshjft·2022년 5월 18일
0

데브코스 TIL

목록 보기
34/45

Thread Per Request, ThreadLocal

Thread Per Request

  • WAS는 ThradPool을 생성한다 (Tomcat 기본값 200)
  • HTTP 요청이 들어오면 Queue에 적재되고, ThreadPool 내의 특정 Thread가 Queue에서 요청을 가져와 처리하게된다.
  • HTTP 요청은 처음부터 끝까지 동일한 Thread에서 처리된다.
  • HTTP 요청 처리가 끝나면 Thread는 다시 ThreadPool에 반납된다.
  • 즉, WAS의 최대 동시 처리 HTTP 요청의 갯수는 ThreadPool의 갯수와 같다
  • Thead 갯수를 늘리면 동시 처리 갯수가 늘어나지만, Thread Context 스위칭에 의한 오버헤드도 커지기 때문에 성능이 선형적으로 증가하지는 않는다.
    • WebFlux의 경우 최대한 적은 수의 스레드를 통해 최대한 많은 수의 요청을 처리한다. 즉 하나의 요청이 다수에 스레드에서 처리 될 수 있다.

ThreadLocal

  • 동일 Thread 내에서는 언제든 ThreadLocal 변수에 접근할 수 있다.
    • 동일 Thread내에서 실행되는 Controller, Service, Repository, 도메인 모델 어디에서든 ThreadLocal 변수에 접근할 수 있다.
  • Thread Pool의 thread에서 ThreadLocal 변수를 사용했다면 반드시 ThreadLocal 변수를 반드시 clear 해야한다. 해당 thread가 다시 사용될 때도 해당 변수가 남아 있기 때문이다. 이는 잘못된 동작 유도할 수 있다.

SecurityContextHolder, SecurityContext, Authentication

SecurityContextHolder

  • SecurityContext를 담는 그릇
  • SecurityContextHolderStrategy가 핵심
    • SecurityContextHolderStrategy의 구현체는 ThreadLocalSecurityContextHolderStrategy
    • Spring Web MVC → thread per Request 기반
    • SecurityContextHolder → thread local을 기반
    • Spring에서 요청 처리한 후에 SecurityContextHolder.clearContext()를 호출하고 있다. (ThreadLocal 변수 제거, FilterChainProxy 참고)

SecurityContext

  • Spring 어디에서든 SecurityContextHolder를 통해 SecurityContext(ThreadLocal 변수에 저장)를 조회할 수 있다.
  • 특별한 기능은 없고 Authentication을 wrapping하고 있다.

Authentication

  • 사용자를 표현하는 인증 토큰 인터페이스이다. 인증 주체(Principal), 비밀번호(Credentials) 권한 목록(Authorities)을 포함하고 있다.
    • AnonymousAuthenticationToken
    • UsernamePasswordAuthenticationToken
      로그인 아이디/비밀번호 기반 Authentication 인터페이스 구현체
    • RememberMeAuthenticationToken
      remember-me 기반 Authentication 인터페이스 구현체
  • 사용자의 인증 완료 여부에 따라 Principal의 값이 달라진다.
    • Before 로그인: 로그인 아이디(String)
    • After 로그인: org.springframework.security.core.userdetails.User 객체

인증 처리

DefaultPageGeneratingFilter

  • HTTP GET 요청에 대해 디폴트 로그인 페이지를 생성해주는 필터이다.
    • 로그인 아이디/비밀번호/Remember-Me 파라미터명을 변경할 수 있다.
      • 아이디: formLogin().usernameParameter(“~~~”)
      • 비밀번호: formLogin().passwordParameter(“~~~”)
      • Remember-Me: rememberMe().rememberMeParameter(“~~~”)
    • 로그인 페이지도 커스텀하게 구현할 수 있다.
    http
    		// ... 생략 ...
    		.formLogin()
    			.loginPage("/mylogin")
    			.permitAll()
    		  .and()
    // ... 생략 ...

AbstractAuthenticationProcessingFilter (UsernamePasswordAuthenticationFilter)

  • 사용자 인증을 처리히가 위한 필터
  • 사용자 인증 정보를 취합하고, Authenticatioin 객체를 생성한다.
    • attemptAuthentication() 메서드에서 로그인 아이디/비밀번호를 취합하고 UsernamePasswordAuthenticationToken 객체를 생성한다.
  • 인증이 완료되지 않은 Authentication 객체는 AuthenticationManager 객체로 전달한다.
  • 인증이 정상적으로 완료되었다면 새롭게 만들어진 Authentication 객체를 반환한다.
    • 인증 완료 후 새롭게 만드러진 객체는 권한(GrantedAuthority) 목록을 가지고 있다.

AuthenticationManager, ProviderManager

  • AuthenticationManager는 interface이며 기본 구현체는 ProviderManager이다.
  • ProviderManager는 AuthenticationProvider를 List로 가지고 있다.
    • AuthenticationProvider들 중 하나가 Authentication을 처리한다.
      • UsernamePasswordAuthenticationToken 타입의 인증 요청은 DaoAuthenticationProvider 처리한다.
      • 인증 과정 중 UserDetailService를 통해 데이터베이스에서 User를 가져온다.
      • 성공적인 인증 후 UserNamePasswordAuthenticationToken을 반환한다.

보면 좋은 글!

profile
꾸준히 나아가자 🐢

0개의 댓글