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의 정보다.
참조
'Spring Security' 카테고리의 다른 글
Spring Security & CSRF & Json Web Token (0) | 2021.12.24 |
---|---|
Authentication과 SecurityContextHolder (0) | 2021.06.03 |
AuthenticationManager와 Authentication (0) | 2021.06.02 |
댓글