스프링 시큐리티 아키텍처

seungho choi·2022년 9월 28일
0

DelegatingFilterProxy 와 FilterChainProxy

  • 서블릿 필터는 스프링에서 정의된 빈을 주입해서 사용할 수 없음
  • 특정한 이름을 가진 스프링 빈을 찾아 그 빈에게 요청을 위임 함

스프링 시큐리티는 서블릿 필터를 이용해 인증 인가 처리를 함 그런데 스프링 시큐리티에서 정의한 필터빈들은 스프링 컨테이너 빈임 그러면 어떻게 하냐 DelegatingFilterProxy 가 특정 스프링 컨테이너에 있는 FilterChainProxy 으로 등록된 빈을 찾아 필터를 위임 함

참고로 DelegatingFilterProxy는 스프링 시큐리티 기술이 아니라 스프링 웹 표준 기술임 스프링의 빈으로 등록하면 스프링 컨텍스트에 등록된 빈을 사용 할 수 있는게 가장 큰 장점임

  1. 유저이 유청이 들어온다.
  2. 요청이 들어와 DelegatingFilterProxy 까지 필터가 전달 되면 DelegatingFilterProxy는 스프링 컨텍스트에 등록된 Bean 이름이 springSecurityFilterChain 으로 된 FilterChainProxy 를 찾는다.
  3. FilterChainProxySpringSecurityConfig 에 등록된 필터들을 순서에 맞게 필터 체이닝 함
  4. 모든 필터를 정상적으로 호출 하면 DispatcherServlet 으로 요청으로 감

Autentication

  • Autentication 는 스프링 시큐리티에서 인증 시 사용자의 인증 정보를 저장하는 토큰 개념의 객체이다
  • 인증 후 최종 인증 결과를 담고 SecurityContext에 저장되어 스프링 전역적 으로 참조가 가능하다.
Authtentication authentication = SeurityContextHolder.getContext().getAuthentication()
  • Authentication 이 담고있는 프로퍼티
    • principal : 사용자 아이디 혹은 User 객체를 저장
    • credentials : 사용자 비밀번호
    • authorites : 인증된 사용자의 권한 목록 Roles
    • details : 인증 부가 정보
    • Authenticated : 인증 여부

Autentication이 사용되는 흐름

  1. username + password form 방식의 요청이 옴
  2. UsernamePasswordAuthenticationAuthentication 객체를 만듬
  3. 만들어진 AuthenticationAuthtenticationManger 를 통해 인증을 함 (실패하면 예외 발생)
  4. 최종 인증이 되면 AuthenticationSecurityContext 에 전역적으로 사용할 수 있음

SeurityContextHolder 와 SecurityContext

SecurityContext

  • Authentication 객체가 저장되는 보관소로 필요시 언제든지 Authentication 객체를 꺼내어 쓸 수 있도록 제공된다

  • TheardLocal에 저장되어 현재 실행되고 있는 스레드에 스택프레임에 있는 곳 아무데서나 사용이 가능하다.

  • 인증이 완료되면 HttpSession 에 저장되어 어플리케이션 전반에 걸쳐 전역적인 참조 가능하다

    SecurityContextHolder

  • SecurityContext 를 담고 있고 SecurityContext 를 현재 쓰레드와 연결 해준다

  • SecurityContext 객체 저장 방식

    • MODE_THREADLOCAL : 스레드당 SecurityContext 객체를 할당 (default) 한다

    • MODE_INHERITABLETHREADLOCAL : 메인 스레드에서 자식 스레드를 생성할 경우 자식 스레드는 메인 스레드의 동일 한SeucirytContext를 유지 한다

    • MODE_GLOBAL : 응용 프로그램에서 단 하나의 SecurityContext 만 존재한다.

      • jvm static 영역에 SecurityContext 를 저장 한다.

SecurityContextPersistenceFilter

  • SecurityContext 의 생성, 조회, 저장 등 라이프 사이클을 관리 하는 필터

  • 매 요청시마다 항상 동작하고 스프링 시큐리티의 2번 째 필터로 등록 되어있다

    • 내부적으로 HttpSecurityContextRepository 를 이용해 영속화를 책임짐 기본적으로 구현체는 HttpSessionSecurityContextRepository 를 사용함

  1. 요청이 들어오면

  2. HttpSecurityContextRepository load 메서드를 이용해 SecurityContext 를 로드 함

    • 기본적으로 HttpSessionSecurityContextRepository를 이용 한다고 했음 session 을 조회해서 만약 session이 존재하지 않으면 SecurityContextauthenticated - false 인 객체를 반환 할거임
  3. load 되었으면 다음 chain 으로 넘긴다 인증되지 않은 SecurityContext 는 인증 처리를 하는 필터를 처리하겠지만 인증된 SecurityContext 는 인증 필터를 처리하지 않을 것임

Authentication Flow

  1. UsernamePasswordAuthenticationFilter 로 id + password 인증 요청이 들어옴

  2. UsernamePasswordAuthenticationFilter는 id + password 를 담은 Authentication 토큰을 생성 함

  3. AuthenticationMangerAuthentication 토큰을 남겨 인증 처리를 위임함

  4. AuthenticationManger 는 실제 인증 역할을 하지 않고 id + password 인증을 하는 적절한 AutenticationProvder 를 찾아 인증 역할을 위임 함

  5. AutenticationProvder 는 실제 인증 처리 역할을 함 유저 유효성 검증 처리 등

    • loadUserByUsername 의 역할은 username 을 이용해 실제 영속화된 객체를 조회함

    • loadUserByUsernameAuthenticationUserDetails 를 반환 함

    • 만약 조회하는데 실패하면 UsernameNotFoundException 을 발생 시켜야 함

  6. AutenticationProvder는 반환받은 UserDetails 와 실제 password를 검증 한다

    • 일치하지 않는 경우 BadCredentialException 예외 발생

    • 검증에 성공 할 경우 UserDetails + UserDetails.authorites 를 이용 해 Authenticaiton 토큰 객체 생성

  7. 그 후 생성된 SecurityContext 토큰을 저장

AuthenticationManager

  • AuthenticationProvider 목록 중에서 인증 처리 요건에 맞는 AuthenticationProvider 찾아 인증을 위임하는 역할

  • 구현체로는 ProviderManager가 있음

  • 부모 ProviderManager 를 설정하여 AuthenticationProvider를 계속 탐색 할 수 있다.

FilterSecurityInterceptor

  • 필터체인 맨 마지막에 위치한 필터로써 인증된 사용자에 대하여 특정 요청의 승인/거부 여부를 최종적으로 결정

  • 인증객체 없이 보호자원에 접근을 시도할 경우 AuthenticationExcetpion 을 발생

  • 인증 후 자원에 접근 가능한이 존재하지 않을 경우 AccessDeniedException 을 발생

  • 권한 제어 방식 중 HTTP 자원의 보안을 처리하는 필터

  • 권한 처리를 AccessDecisionManager에게 맡김

  1. FilterSecurityInterceptor 에서 요청을 받으면 Authentication의 인증객체 여부를 체크 함

    • Authenticationnull 이면 AuthenticationException 예외를 던져 ExceptionTranslationFilter가 예외 처리를 함
  2. Authentication 객체가 null이 아니면 SecurityMetadataSource 에서 권한 정보들을 가져 옴

    • SecurityMetadataSourcenull 일 경우 권한 심사를 하지 않고 바로 자원 접근 허용 함
  3. 권한 정보가 있을 경우 FilterSecurityInterceptorAccessDecisionManager 에게 권한 심사를 위임 함

    • 승인 거부 할경우 AccessDeniedException 예외를 터트려 ExceptionTranslationFilter 가 예외 처리를 함

0개의 댓글