[Spring Security & Redis] UsernamePasswordAuthenticationToken
UsernamePasswordAuthenticationToken
Spring Security에서 인증 처리에 사용하는 대표적인 Authentication 구현체이다.
핵심은 같은 클래스를 로그인 요청 객체로도 사용하고, 인증 완료 객체로도 사용한다는 점이다.
또한 생성자 인자 개수(2개 / 3개)에 따라 역할이 달라진다.
1. Authentication 객체의 핵심 구성요소
Spring Security의 인증 객체는 크게 3가지 정보를 가진다.
principal 이란?
로그인하려는 사용자를 식별하는 값이다.
예:
- username
- loginId
- 인증 완료 후 UserDetails 객체
1
principal = "user@test.com"
credentials 란?
사용자가 진짜 본인인지 증명하는 값이다.
대표적으로:
- password
- OTP 번호
- JWT 토큰
- 인증서 로그인에서는 보통 비밀번호가 들어간다.
1
credentials = "1234"
즉:
principal 은 누구인지
authorities 란?
인증된 사용자의 권한 정보이다.
예:
1
2
ROLE_USER
ROLE_ADMIN
2. 왜 principal / credentials 가 Object 타입일까?
Spring Security는 다양한 인증 방식을 지원해야 한다.
예:
- 일반 로그인 → email + password
- OTP 로그인 → phone + code
- JWT 로그인 → user + token
- OAuth 로그인 → social user info 그래서 타입을 고정하지 않고:
1
2
Object principal
Object credentials
로 설계되었다.
3. 생성자 2개짜리 vs 3개짜리 차이
2-argument 생성자 → 인증 요청용
1
2
3
4
new UsernamePasswordAuthenticationToken(
principal,
credentials
)
예:
1
2
3
4
new UsernamePasswordAuthenticationToken(
email,
password
)
내부 상태:
1
authenticated = false
의미:
아직 인증되지 않은 상태
3-argument 생성자 → 인증 완료용
1
2
3
4
5
new UsernamePasswordAuthenticationToken(
principal,
credentials,
authorities
)
예:
1
2
3
4
5
new UsernamePasswordAuthenticationToken(
userDetails,
null,
authorities
)
내부 상태:
1
authenticated = true
의미:
인증 완료 상태
4. email / password 넣는 게 맞는가?
많이 헷갈리는 부분이다.
1
2
3
4
new UsernamePasswordAuthenticationToken(
email,
password
)
이렇게 작성하는 것은 정상적인 표준 방식이다.
여기서:
즉:
나는 user@test.com 이고
라는 요청 객체이다.
5. credentials 에 password 넣는 게 왜 중요한가?
절대 무의미하지 않다.
로그인 인증의 핵심 데이터이다.
Spring Security 내부에서 비밀번호 비교에 사용된다.
1
2
3
4
5
6
7
8
9
10
String inputPassword =
authentication.getCredentials().toString();
String dbPassword =
userDetails.getPassword();
passwordEncoder.matches(
inputPassword,
dbPassword
);
즉:
- 사용자가 입력한 비밀번호
- DB에 저장된 암호화 비밀번호 를 비교해서 로그인 성공 여부를 판단한다.
6. 로그인 성공 후 credentials 가 null 인 이유
인증 완료 후에는 비밀번호를 계속 들고 있을 필요가 없다.
그래서 보통:
1
2
3
4
5
new UsernamePasswordAuthenticationToken(
userDetails,
null,
authorities
)
이렇게 만든다.
이유:
- 인증 이미 끝남
- 비밀번호 메모리 보관 위험
- 보안상 제거하는 것이 안전함
7. 전체 로그인 흐름
[1단계] 로그인 요청
사용자가 이메일 / 비밀번호 입력
1
2
email = "user@test.com"
password = "1234"
This post is licensed under CC BY 4.0 by the author.