본문 바로가기
Spring Security

SecurityContextHolder와 Authentication

by 홍굴이 2021. 6. 2.

SecurityContextHolder

  • SecurityContext 제공, 기본적으로 ThreadLocal을 사용한다.
  • ThreadLocal 이란?
    • 한 쓰레드 내에서 Share 하는 저장소 → 즉, 메소드 파라미터를 사용하지 않아도 한 쓰레드 내에서 공유하기 때문에 데이터에 접근할 수 있다.

SecurityContext

  • Authentication 제공

Authentication

  • Principal과 GrantAuthority 제공

Principal

  • "누구"에 해당하는 정보
  • UserDetailsService에서 리턴한 객체
  • 객체는 UserDetails 타입

GrantAuthority

  • ROLE_USER, ROLE_ADMIN 등 Principal이 가지고 있는 권한을 나타낸다.
  • 인증 이후, 인가 및 권한 확인할 때 이정보를 참조한다.

UserDetails

  • 애플리케이션이 가지고 있는 유저 정보와 Spring Security가 사용하는 Authenticaiton 객체 사이의 어댑터

UserDetailsService

  • 유저 정보를 UserDetails 타입으로 가져오는 DAO 인터페이스
  • 유저 정보를 Spring Security 한테 제공하는 역할을 한다.
  • 실제로 검증을 하는 것은 AuthenticationManager 이다.

실제 정보를 가져오는 테스트

package com.example.demo.form;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.Collection;

@Service
public class SampleService {

    /**
     * SecurityContext 안에 있는 Principal 정보를 찾고 싶을 때,
     * SecurityContextHolder 만 기억하면 찾을 수 있다.
     * SecurityContextHolder 그림을 기억하자
     */
    public void dashboard() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        // 인증을 한 사용자의 정보
        Object principal = authentication.getPrincipal();
        // 인증을 한 사용자의 권한
        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
        Object credentials = authentication.getCredentials();
        boolean authenticated = authentication.isAuthenticated();
    }
}

디버그 모든 정보

authentication 정보로 Principal, GrantedAuthority, Credentials 정보를 확인할 수 있다.

 

아래 코드로 인해 SecurityContextHolder 안에 SecurityContext 안에 Authentication 정보를 찾을 수 있다.

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

Return 타입이 UsernamePasswordAuthenticationToken 이 되는 것을 디버그 모드에서 확인할 수 있는데, 아래 그림을 통해서 데이터를 확인할 수 있다.

UsernamePasswordAuthentication Class는 Principal과 Crendentials를 가지고 있고, AbstractAuthenticationToken을 상속받고 있다.

AbstractAuthenticationToken Class는 GrantedAuthority와 authenticated를 가지고 있다.

이렇게 해서 아래 코드로 인해 Authentication 객체로 Principal과 GrantAuthority를 찾을 수 있다.

// 인증을 한 사용자의 정보
Object principal = authentication.getPrincipal();
// 인증을 한 사용자의 권한
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();

Return 타입이 Prinipal 은 User.class로 되어 있고, GrantAuthority는 SimpleGrantedAuthority로 되어있다.

Principal의 User.class는 앞서 공부했던 UserDetails의 정보다.

 

 

참조

https://www.inflearn.com/course/%EB%B0%B1%EA%B8%B0%EC%84%A0-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0#

'Spring Security' 카테고리의 다른 글

Spring Security & CSRF & Json Web Token  (0) 2021.12.24
Authentication과 SecurityContextHolder  (0) 2021.06.03
AuthenticationManager와 Authentication  (0) 2021.06.02

댓글