Authentication
| "누가, 어떤 자격으로, 인증되어 시스템에 접근하고 있는가?"
- Spring Security에서 인증된 사용자 정보 전체를 담는 객체
- 사용자가 로그인에 성공하면 생성되고, SecurityContext에 저장
- SecurityContextHolder를 통해 전역적으로 접근 가능
Authentication 객체의 주요 구성 요소
Authentication은 인터페이스이며, 직접 구현하지 않아도 Spring Security가 구현체를 제공
대표적인 구현체는 "UsernamePasswordAuthenticationToken"
- getPrincipal() : 인증된 사용자에 대한 정보를 제공하는 객체를 반환 (일반적으로 UserDetails나 Principal)
- getAuthorities() : 사용자의 권한 목록 (예: ROLE_USER, ROLE_ADMIN)
- getCredentials() : 인증 자격 증명 (예: 비밀번호, 인증 토큰)
- isAuthenticated() : 사용자가 인증되었는지 여부를 반환
주요 필드
| principal | Object | 로그인한 사용자의 정보 (보통 UserDetails) |
| credentials | Object | 자격 증명 (ex. 비밀번호) |
| authorities | Collection<? extends GrantedAuthority> | 권한 목록 (ROLE_USER, ROLE_ADMIN 등) |
| authenticated | boolean | 인증 여부 (true/false) |
| details | Object | 요청 정보 (IP 주소 등 부가 정보) |
로그인 시의 인증 과정 (Username/Password 기반 예시)
1. 사용자가 아이디/비밀번호로 로그인 요청
2. Spring Security 필터 체인 중 UsernamePasswordAuthenticationFilter가 요청 가로챔
3. 해당 필터는 사용자의 입력을 기반으로 Authentication 객체 생성:
→ new UsernamePasswordAuthenticationToken(username, password)
(이 시점에서는 아직 authenticated = false)
4. 이 Authentication 객체를 AuthenticationManager에게 전달
5. AuthenticationManager는 UserDetailsService를 이용해 사용자 정보 조회
6. 비밀번호 등 검증 성공 시, → 새로운 Authentication 객체를 만들고 authenticated = true 설정
7. SecurityContextHolder에 최종 인증된 Authentication 저장
UsernamePasswordAuthenticationToken
Authentication 인터페이스의 구현체 중 하나
- 인증 전 상태
new UsernamePasswordAuthenticationToken("username", "password");
// 인증되지 않은 상태 (authenticated = false)
- 인증 후 상태
new UsernamePasswordAuthenticationToken(principal, null, authorities);
// 인증된 상태 (authenticated = true)
Spring Security 내부에서 이 객체가 계속 재사용
Principal
- Java의 보안 인터페이스 java.security.Principal
- Spring Security에서도 인증된 사용자 정보를 표현할 때 이 인터페이스를 사용
- Authentication의 getPrincipal() 메서드가 반환하는 객체가 바로 Principal
- Spring Security에서는 Principal이 UserDetails 객체일 수도 있고, 사용자 정의 객체일 수도 있다.
- 단순한 정보만 들어있습니다. 주로 사용자 이름 (username)
PrincipalDetails 클래스
PrincipalDetails는 Spring Security가 인증 후 세션에 저장하는 사용자 정보 객체
OAuth2User 혹은 UserDetails 인터페이스를 구현하여 다음 두 로그인 방식에 공통으로 사용
- UserDetails → 일반 로그인용
- OAuth2User → OAuth2 로그인용
💡 이걸 직접 만든 이유는 일반 로그인과 소셜 로그인(OAuth2)을 모두 지원하는 통합된 사용자 인증 객체를 만들기 위함
왜 PrincipalDetails가 있어야 할까?
- @AuthenticationPrincipal로 접근 가능한 사용자 객체는 Spring Security에서 관리하는 Principal이다.
- 이 Principal을 통해 우리가 원하는 사용자 정보(memberId, nickname, role 등)를 편리하게 가져오기 위해 PrincipalDetails 클래스에서 직접 꺼내 쓸 수 있게 만든다.
예시:
Long memberId = principalDetails.getUserId(); // 직접 정의한 메서드