스프링 시큐리티 JWT 정리


- 서블릿 필터 체인의 DelegatingFilter → Security 필터 체인 (내부 처리 후) → 서블릿 필터 체인의 DelegatingFilter 계속해서 진행
가로챈 요청은 SecurityFilterChain에서 처리 후 상황에 따른 거부, 리디렉션, 서블릿으로 요청 전달을 진행한다.
- SecurityFilterChain의 필터 목록과 순서



// AbstractAuthenticationProcessingFilter.java (Simplified)
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
try {
// 1. 자식 클래스(e.g., UsernamePasswordAuthenticationFilter)의 인증 시도
// 이 안에서 authenticationManager.authenticate()가 호출됨
Authentication authResult = attemptAuthentication(request, response);
if (authResult == null) {
return; // 인증이 아직 진행 중이거나 다른 필터에 위임된 경우
}
// 2. 인증 성공! successfulAuthentication 메서드 호출
successfulAuthentication(request, response, chain, authResult);
} catch (AuthenticationException failed) {
// 3. 인증 실패! unsuccessfulAuthentication 메서드 호출
unsuccessfulAuthentication(request, response, failed);
}
}
인증에 성공하면
//로그인 성공시 실행하는 메소드
@Override
protected void successfulAuthentication {
}
내가 오버라이드한 메소드 실행된다.
우선 필터단은 @Controller, @Service와 같이 Bean으로 등록되어 있지 않기 때문에 의존성 주입이 불가능합니다. Config 파일을 통해 직접 생성자 호출해 넣어줘야 한다.
암호화 과정
### 1. 암호화 (Encode) 과정
memberService.create()
에서 passwordEncoder.encode("password1234")
가 호출되면, DelegatingPasswordEncoder
는 다음과 같이 동작합니다.
현재 가장 안전하다고 여겨지는 기본 알고리즘 (현재는 BCrypt)을 선택하여 비밀번호를 해싱합니다.
해싱된 값 앞에 **어떤 알고리즘을 사용했는지 알려주는 접두사
{bcrypt}
**를 붙입니다.이 전체 문자열을 데이터베이스에 저장합니다.
DB에 저장되는 값 예시:
{bcrypt}$2a$10$N9qo8uLOickgx2ZMRZoMye.aA.w2.3jIuQwwzVm7s.xQ23s7f4Y.e
### 2. 비교 (Matches) 과정
memberService.login()
에서 passwordEncoder.matches("password1234", dbPassword)
가 호출되면, DelegatingPasswordEncoder
는 다음과 같이 동작합니다.
DB에서 가져온 암호화된 비밀번호(
dbPassword
)의 접두사를 먼저 확인합니다. (e.g.,{bcrypt}
)"아, 이 비밀번호는
bcrypt
로 암호화되었구나!"라고 인지합니다.자신이 내부적으로 가지고 있는 여러 암호화기(BCrypt, SCrypt 등) 중에서
BCryptPasswordEncoder
를 찾아냅니다.실제 비교 작업은 해당
BCryptPasswordEncoder
에게 위임합니다.BCryptPasswordEncoder
가 사용자가 입력한 "password1234"를 BCrypt로 해싱하여 DB 값과 비교한 후, 그 결과를 반환합니다.
추가로 개발 및 공부 해야할 자료
Refresh Token 및 Logout 구현
실제 스프링 시큐리티 내부구조 공
Last updated