2025.02.25, 화

김바실리

도식


          ┌────────────────────────────┐
          │        클라이언트             │
          │  (로그인 요청: /authenticate) │
          └─────────────┬──────────────┘
                        │
                        ▼
          ┌────────────────────────────┐
          │      SecurityConfig        │
          │  - 필터 체인 설정             │
          │  - AuthenticationManager   │
          └─────────────┬──────────────┘
                        │
                        ▼
          ┌────────────────────────────┐
          │ UsernamePasswordAuthFilter │
          │ (또는 DelegatingFilterProxy)│
          └─────────────┬──────────────┘
                        │
                        ▼
          ┌──────────────────────────────────┐
          │  JwtFilter (커스텀 필터)            │
          │  - 요청 헤더에서 JWT 추출             │
          │  - 토큰 검증 및 Authentication 생성  │
          └─────────────┬────────────────────┘
                        │   (JWT 토큰이 없으면 AnonymousAuthentication)
                        ▼
          ┌────────────────────────────┐
          │ AuthenticationManager      │
          │   (ProviderManager)        │
          └─────────────┬──────────────┘
                        │
                        ▼
          ┌────────────────────────────┐
          │ DaoAuthenticationProvider  │◄─────┐
          │  - UserDetailsService 호출  │      │
          └─────────────┬──────────────┘      │
                        │                     │
                        ▼                     │
          ┌────────────────────────────┐      │
          │ JwtUserDetailsService      │      │
          │  - loadUserByUsername()    │      │
          │  - DB에서 User 조회          │      │
          │  - createUser() : JwtUser  │      │
          └─────────────┬──────────────┘      │
                        │                     │
                        ▼                     │
          ┌────────────────────────────┐      │
          │  DaoAuthenticationProvider │──────┘
          │  - 비밀번호, 계정 상태 검증      │
          │  - Authenticated Token 생성 │
          └─────────────┬──────────────┘
                        │
                        ▼
          ┌────────────────────────────┐
          │ SecurityContextHolder      │
          │  - 인증 정보 저장             │
          └─────────────┬──────────────┘
                        │
                        ▼
          ┌────────────────────────────┐
          │ AuthController             │
          │  - JWT 토큰 생성             │
          │    (JwtTokenProvider)      │
          │  - 토큰 DB 업데이트           │
          │  - 클라이언트에 토큰 전달       │
          └────────────────────────────┘

단계별 순서 설명


  1. 클라이언트 로그인 요청
    1. 클라이언트가 /authenticate 엔드포인트로 로그인 요청을 보냅니다.
    2. 요청 본문에는 로그인 식별자(loginId)와 비밀번호가 포함됩니다.
  2. SecurityConfig 설정 적용
    1. SecurityConfig에서 HttpSecurity를 구성하여, 필터 체인을 설정합니다.
    2. 여기에는 JWT 필터(JwtFilter)를 UsernamePasswordAuthenticationFilter 이전에 등록하고, 인증/인가 규칙을 정의합니다.
    3. 또한 AuthenticationManager가 구성되어 DaoAuthenticationProvider 등 여러 인증 제공자들이 사용됩니다.
  3. 인증 필터 동작
    1. 로그인 요청은 UsernamePasswordAuthenticationFilter(또는 그에 해당하는 필터)에 의해 가로채집니다.
    2. 이 필터는 로그인 정보로 UsernamePasswordAuthenticationToken을 생성하여 AuthenticationManager에 전달합니다.
  4. JwtFilter 동작 (JWT 검증)
    1. JWT 토큰이 존재하면 JwtFilter가 토큰을 추출하고, JwtTokenProvider를 사용해 토큰을 검증합니다.
    2. (로그인 요청 시에는 아직 JWT가 없을 수 있으므로, 익명 인증이 설정됩니다.)
  5. AuthenticationManager 처리
    1. AuthenticationManager(ProviderManager)는 여러 AuthenticationProvider 중 DaoAuthenticationProvider를 호출합니다.
  6. DaoAuthenticationProvider & JwtUserDetailsService
    1. DaoAuthenticationProvider는 UserDetailsService, 여기서는 JwtUserDetailsService의 loadUserByUsername(loginId)를 호출합니다.
    2. JwtUserDetailsService는 DB(UserRepository)를 조회하여, 해당 loginId에 맞는 User 엔티티를 찾습니다.
    3. 조회된 User 엔티티를 기반으로 createUser(User) 메서드가 호출되어,
      1. 사용자 역할(user.getRole().name())을 SimpleGrantedAuthority로 변환한 후,
      2. JwtUser 객체를 생성합니다.
      3. 생성자에서 로그로 JwtUser의 정보(예: “Username=basilry”)가 출력됩니다.
  7. 비밀번호 검증 및 인증 토큰 생성
    1. DaoAuthenticationProvider는 입력된 비밀번호와 DB에서 로드한 UserDetails의 암호를 비교합니다.
    2. 인증이 성공하면, Authenticated Authentication 객체(UsernamePasswordAuthenticationToken)가 생성되어 반환됩니다.