Spring Security - SecurityContextHolder / SecurityContext / Authentication / GrantedAuthority

TopOfTheHead·2025년 11월 18일

Spring Security

목록 보기
4/27

SecurityContextHolder / SecurityContext / Authentication 관계

SecurityContextHolder
   └── SecurityContext (보안 컨텍스트)
         └── Authentication (인증 정보)
               ├── Principal (사용자 정보)
               ├── Credentials (비밀번호, JWT 등)
               └── Authorities (권한 정보)

Authentication \in SecurityContext \in SecurityContextHolder

SecurityContextHolder :
。현재 실행중인 threadSecurityContext를 저장 및 관리하는 저장소 객체
ThreadLocal을 기반으로 동작하여 ThreadSecurityContext객체를 독립적으로 관리

스레드인증이 완료된 개별 사용자의 인증정보가 포함된 Authentication 구현체가 저장된 사용자 별 고유한 SecurityContext객체를 저장.
어플리케이션 어디에서든지 현재 로그인한 사용자 인증정보가 포함된 Authentication 구현체를 가져올 수 있음.

  • SecurityContextHolderSpring Bean이 아닌 ThreadLocal 기반인 이유?
    SecurityContextHolder를 만약에 Spring Bean으로 등록하는 경우, 전체 사용자가 해당 SecurityContextHolder싱글톤으로서 서로 공유하는 문제점이 존재
    ▶ 다른 사용자SecurityContextAuthentication의 보안이 필요한 필드에 접근 가능.

    。따라서, ThreadLocal을 통해 각 사용자스레드마다 독립적인 Security Context를 제공
    Tomcat의 경우 사용자 요청스레드 하나를 할당하므로 각 사용자는 고유한 Security Context를 가질 수 있다.

  • ThreadLocal java.lang.ThreadLocal
    스레드 마다 독립적인 을 저장할 수 있게하는 Java Class
    VIEWModel 객체 같은 느낌

    ThreadLocal을 통해 Thread Safe를 제공
    ▶ 동일한 SecurityContextHolder 내 에서도 스레드 별로 서로 다른 Security Cotext를 가질 수 있음.

    。해당 ThreadLocal가 가진 SecurityContextAuthentication 객체를 유일하게 관리하도록 설정하여 동시참조를 차단

SecurityContext :
。현재 로그인사용자인증정보 ( Authentication )를 포함하는 Container 역할의 객체
AuthenticationProvider에 의해 인증이 완료된 Authentication 구현체를 저장

SecurityContextHolder에서 스레드 별로 저장 및 관리가 수행되며 SecurityContextHolder를 통해 접근 가능.

SecurityContext 내부에 현재 스레드로그인 중인 Authentication 객체principalController@AuthenticationPrincipal을 통해 UserDetails 구현체의존성 주입하여 현재 로그인 사용자principal 정보를 전달이 가능

  • WAS를 통한 별도의 스레드로 접속한 각 사용자인증이 완료되어 완전히 생성된 Authentication 구현체SecurityContextHolder스레드 별로 구분된 Security Context에 저장
    。인증이 완료된 Authentication 구현체스레드 별로 할당된 SecurityContext에 저장되므로, 다른 스레드에서 해당 Authentication 구현체를 조회할 수 없다.

Authentication :
org.springframework.security.core.Authentication
Spring Security에서 사용자의 Authentication 정보를 추상화하는 인터페이스
사용자정보 ( principal ) , 권한정보 ( authorities ) , 토큰 ( credentials ) 등을 포함.

Authenticationauthorities는 여러개의 권한 ( Collection<GrantedAuthority> )를 가질 수 있다.
▶ 하나의 User는 여러 역할을 가질 수 있음.

  • 인증을 수행 시 로그인 정보credentials에 포함 후 생성하여 활용되고, 인증이 끝난 후 완전한 Authentication 구현체로서 SecurityContextHoder스레드별 SecurityContext에 저장
    로그인 수행 시 credentials를 포함한 Authentication 구현체를 생성 후 인증이 완료된 경우 DB에서 해당 사용자 정보를 포함하는 UserDetails 구현체를 생성하여 principalauthorities를 포함한 완전한 Authentication 구현체를 생성 후 SecurityContextHolder현재 스레드SecurityContext로 등록

  • Authentication 구현체Spring Bean이 아닌, ThreadLocal 환경에서 관리
    Security Context HolderThreadLocal 기반인 이유

    AuthenticationSpring Context 내 저장 시 싱글톤으로 관리되는 경우 해당 Authentication으로 다른 사람이 의존성 주입받아서 해당 Authentication 정보를 확인하는 단점이 존재하므로.
    ThreadLocal은 각각의 사용자스레드마다 SecurityContext를 통해 서로 격리되어 다른 스레드에서 Authentication 구현체를 조회할 수 없다.

  • Authentication 구현체 구조
    ex) 클라이언트에서 전송된 HTTP RequestHTTP Basic Authentication 인증정보가 포함된 경우의 서버에서 생성된 Authentication 구현체의 구조

    principal :
    。인증된 사용자세부정보를 의미.
    ▶ 보통 UserDetails 객체의 내용을 포함

    CurrentUser principal = (CurrentUser) authentication.getPrincipal();
    ▶ 다음처럼 가져온 후 UserDetails 객체캐스팅해서 활용

    credentials
    。사용자가 인증 시 입력한 인증정보를 포함 ( ex. username, password , JWT Token )

    。초기 HTTP RequestAuthorization Header에 포함된 인증정보credentials에 포함한 Authentication 객체 생성 및 AuthenticationManager에 의한 검증 수행
    검증이 끝난 후 Authentication 객체principalauthorities는 포함하고 credentials는 보안을 위해 null로 설정

    authorities
    principal에 정의된 사용자가 보유한 역할, 권한 목록을 지시.

    Collection<GrantedAuthority> 객체를 포함하여 여러 역할을 가질 수 있다.
    ▶ 주로 "ROLE_USER" , "ROLE_ADMIN" 등의 권한정보를 포함.

GrantedAuthority
Spring Security에서 사용자 권한 정보( Role / Authority )를 표현하는 인터페이스
▶ 현재 인증사용자권한을 포함하는 컨테이너 객체 역할을 수행

Role을 설정 시 예전에는 prefix : ROLE_사용자가 정의해야했지만, 현재는 Spring 내부에서 자동으로 적용
▶ 사용자가 MEMBER권한명으로 설정 시 ROLE_MEMBER로 자동으로 반영
ex) ROLE_ADMIN, ROLE_MEMBER

public interface GrantedAuthority extends Serializable {
    String getAuthority();
}

GrantedAuthority는 단순히 문자열 권한 ( "ROLE_USER", "ROLE_ADMIN" )을 감싸는 역할의 객체

UserDetails userDetails =
    User.builder()
        .username("user")
        .password("1234")
        .roles("USER")
        .build();

。해당 UserDetails 구현체"ROLE_USER"로서 GrantedAuthority 구현체로 저장
▶ 주로 UserDetails 구현체, Authentication 구현체 내부에 Collection<GrantedAuthority>로서 저장되어 권한 인가 시 활용

  • SimpleGrantedAuthority
    Spring Security에서 기본적으로 사용하는 GrantedAuthority 구현체
    getAuthority()메서드 오버라이딩사용자 권한(Role / Authority)을 단순한 문자열 형태로 저장하는 객체
@Override
	public Collection<? extends GrantedAuthority> getAuthorities() {
		return List.of(new SimpleGrantedAuthority("ROLE_" + role.name()));
	}

。 보통 UserDetails에서 getAuthorities()를 통해 반환됨
{ ROLE_USER }

profile
공부기록 블로그

0개의 댓글