포스트

Spring Security - 1

Servlet Authentication Architecture


SecurityContextHolder

출처 : Spring Security Docs

Spring Security 가 인증된 사용자의 세부 정보를 저장하는 곳

1
2
3
4
5
6
SecurityContext context = SecurityContextHolder.createEmptyContext();
Authentication authentication =
    new TestingAuthenticationToken("username", "password", "ROLE_USER");
context.setAuthentication(authentication);

SecurityContextHolder.setContext(context);
  1. SecurityContext 를 생성합니다.
    • Multi Threads 에서의 Race conditions 를 피하기 위해 SecurityContextHolder.getContext().setAuthentication(authentication) 대신 새 SecurityContext 인스턴스를 만들어야 합니다.
  2. Authentication 객체를 생성합니다.
    • Spring SecuritySecurityContext 에 어떤 유형의 인증 구현이 설정되어 있는지는 신경 쓰지 않습니다.
    • 일반적인 Production ScenarioUsernamePasswordAuthenticationToken(userDetails, password, authorities) 입니다.
  3. 마지막으로 SecurityContextHolder 에서 SecurityContext 를 설정합니다.
    • Spring SecurityAuthorization 을 위해 해당 정보를 사용합니다.
특징
  • ThreadLocal : 기본 Strategy
    • 동일 Thread 내의 메소드들이 명시적으로 SecurityContext 를 전달받지 않아도 이에 접근할 수 있게 해줍니다.
    • 현재 pricipal 의 요청이 처리된 후 Thread 를 정리하는 것에 주의한다면 매우 안전합니다.
  • Spring SecurityFilterChainProxy 는 요청 처리 후 SecurityContext 를 항상 정리해 보안상의 문제를 예방합니다.
  • Strategy
    • SecurityContextHolder.MODE_GLOBAL : JVM 내의 모든 Thread 가 동일한 SecurityContext 사용
    • SecurityContextHolder.MODE_INHERITABLETHREADLOCAL : Security Thread 에 의해 생성된 자식 Thread 가 부모의 Security Identity 상속

SecurityContext

SecurityContextHolder로부터 얻어지며 인증된 사용자의 정보를 담고 있는 Authentication 객체를 포함합니다.

Authentication

1. 사용자가 제공한 자격 증명을 AuthenticationManager 에 입력하여 인증을 시도할 때
  • isAuthenticated() = false
2. 현재 인증된 사용자를 나타낼 때
  • SecurityContext 에서 현재 Authentication 을 얻을 수 있습니다.
구성
  • Principal
    • UserDetails 의 인스턴스
    • 식별된 사용자 정보를 보관
    • 시스템에 따라 UserDetails 클래스를 상속하여 커스텀한 형태로 유지할 수 있습니다.
  • Credentials
    • 사용자(주체)가 올바르다는 것을 증명하는 자격 증명
    • 보통 비밀번호를 의미합니다.
  • Authorities
    • AuthenticationManager 가 설정한 권한
    • Authentication 상태에 영향을 주지 않거나 수정할 수 없는 인스턴스를 사용해야 합니다.

GrantedAuthority

사용자에게 부여된 high-level permission, 주로 역할(role)이나 범위(scope)와 같은 형태

  • Authentication.getAuthority() 메소드를 통해 얻을 수 있는 GrantedAuthority 객체의 Collection 으로 제공됩니다.
  • 일반적으로 애플리케이션 전체의 권한을 나타내며 특정 도메인 객체에 국한되지 않습니다.
    • ROLE_ADMIN, ROLE_USER와 같은 역할을 통해 사용자가 수행할 수 있는 작업의 범위를 정의합니다.

AuthenticationManager

SpringSecurityFilter 가 인증을 수행하는 방법을 정의하는 API

  • Filter 를 통해 인증이 수행된 후, 반환된 Authentication 객체는 SecurityContextHolder 에 설정됩니다.

ProviderManager

AuthenticationManager 의 가장 일반적인 구현체

  • AuthenticationProvider 인스턴스로 구성된 목록에 인증 처리를 위임합니다.
  • AuthenticationProvider 다음과 같은 판단 기회를 가집니다.
    • 인증이 성공적이었는지, 실패했는지
    • 결정을 내릴 수 없어 다음 AuthenticationProvider 에게 결정을 넘길지
  • ProviderNotFoundException
    • AuthenticationProvider 가 어느 인증도 수행할 수 없을 시 발생
    • ProviderManager 가 전달된 인증 유형을 지원하도록 구성되지 않았음을 나타냅니다.

출처 : Spring Security Docs

AuthenticationProvider 는 특정 유형의 인증을 수행하는 방법을 가집니다.

  • username / password
  • saml assertion
  • etc..

이를 통해 다양한 인증 유형을 지원하면서 단일 AuthenticationManager Bean 을 노출할 수 있습니다.
만약 모든 AuthenticationProvider 가 인증을 처리할 수 없는 경우, 선택적으로 구성된 부모 AuthenticationManager 에게 인증을 위임합니다.

출처 : Spring Security Docs

여러 ProviderManager 인스턴스가 같은 부모 AuthenticationManager 를 공유할 수 있습니다.

  • 특정 인증을 공통으로 사용하면서도 다른 인증 메커니즘을 가진 여러 SecurityFilterChain 인스턴스가 존재하는 시나리오에서 흔히 볼 수 있습니다.
특징

ProviderManager 는 성공적인 인증 후 반환된 Authentication 객체에서 민감한 자격 증명 정보를 제거 시도

  • 비밀번호 같은 정보가 HttpSession 에 필요 이상으로 유지되는 것을 방지
  • stateless 애플리케이션의 성능 향상을 위해 사용자 객체 캐시를 사용할 때 문제가 발생할 수 있습니다.
    • 자격 증명 정보가 제거된 UserDetails 인스턴스 같은 캐시된 객체에 대해 다시 인증을 시도할 수 없게 되기 때문

    • 해결 방법

      • 객체의 복사본을 생성
      • ProviderManagereraseCredentialsAfterAuthentication 속성 비활성화

AuthenticationProvider

ProviderManager 는 여러 AuthenticationProvider 인스턴스를 수용할 수 있으며 각각 특정 유형의 인증을 담당합니다.

  • DaoAuthenticationProvider
  • JwtAuthenticationProvider
  • etc..

AuthenticationEntryPoint

클라이언트에게 자격 증명을 요청하는 HTTP 응답을 보내는 데 사용

  • 인증되지 않은 요청을 할 때 (권한이 없는 리소스에 접근하려 할 때) 클라이언트로부터 자격 증명을 요청하기 위해 사용됩니다.
  • 로그인 페이지로의 리다이렉트나 WWW-Authenticate 헤더 응답 등의 동작을 수행할 때 구현이 필요합니다.

AbstractAuthenticationProcessingFilter

출처 : Spring Security Docs

사용자 credentials 를 인증하기위한 기본 필터

Reference

✔ Spring Security DocsSpring Security
이 글은 저작권자의 CC BY 4.0 라이센스를 따릅니다.