반응형
Notice
Recent Posts
Recent Comments
Link
관리 메뉴

짧은코딩

MSA에서 백엔드는 어떻게 인증/인가를 할까 본문

MSA 공부

MSA에서 백엔드는 어떻게 인증/인가를 할까

5_hyun 2025. 7. 15. 23:42
반응형

Spring Boot로 회원가입/로그인을 만들고, Nest로 블로그 서비스 CRUD를 만들다 보니까 들은 생각이 있었다.

MSA는 서로 인증/인가를 어떻게 할까? 처음에는 Spring Boot로 만든 인증/인가 서비스에서 모든 처리를 하면 되겠다고 생각을 했다. 하지만 이 방식은 뭔가 허술하다는 것을 느꼇고, MSA에서 인증/인가를 구현하는 방식을 찾아보고 그 중에서 제일 괜찮은 방식을 적용해야 겠다고 생각했다.

1. API 게이트웨이

설명

  • API 게이트웨이는 마이크로서비스 아키텍처에서 클라이언트와 백엔드 서비스 사이의 프록시(Proxy) 서버 역할을 하는 핵심 컴포넌트
  • 인증/인가 관점에서 게이트웨이는 모든 외부 요청에 대한 단일 진입점(Single Point of Entry)으로 동작하며, 보안 관련 로직을 중앙에서 처리

과정

Step 1: 게이트웨이 필터/미들웨어에서의 인증 처리

  • API 게이트웨이는 라우팅 로직을 실행하기 전에, 사전에 정의된 필터 체인(Filter Chain) 또는 미들웨어(Middleware)를 통해 요청을 처리
  • 이 필터 중 하나가 인증 필터(Authentication Filter)의 역할을 수행
  • 인증 필터의 핵심 로직:
    1. Authorization 헤더에서 JWT(JSON Web Token)를 추출
    2. 미리 설정된 Secret KeyPublic Key를 사용하여 토큰의 서명(Signature)을 검증합니다. 서명이 유효하지 않으면, 이 요청은 위조된 것으로 간주
    3. 토큰의 Payload에 포함된 만료 시간(exp claim)을 현재 시간과 비교하여 토큰이 만료되지 않았는지 확인
    4. 발급자(iss claim) 등 기타 클레임들이 유효한지 검증
  • 만약 위 과정 중 하나라도 실패하면, 게이트웨이는 즉시 401 Unauthorized 또는 403 Forbidden HTTP 상태 코드로 응답하고 요청 처리를 중단
  • 이로써 유효하지 않은 트래픽이 내부망으로 유입되는 것을 원천 차단

Step 2: 요청 재구성 및 다운스트림 서비스로 전파

  • 인증에 성공하면, 게이트웨이는 다운스트림(내부) 서비스가 신뢰하고 사용할 수 있도록 요청을 재구성
  • 헤더 변조/추가:
    • 보안을 위해 외부에서 사용된 Authorization 헤더를 제거
    • 검증된 JWT의 Payload에서 사용자 식별자(sub claim, 보통 User ID)나 역할(Role) 정보를 추출하여, 신뢰할 수 있는 새로운 내부용 헤더에 담아줌 (예: X-User-ID: 12345, X-User-Roles: ADMIN,USER)
  • 이러한 헤더 추가는 다운스트림 서비스가 사용자를 신뢰하고 인가 처리를 쉽게 할 수 있도록 함

Step 3: 라우팅 (Routing)

  • 게이트웨이는 요청 경로(예: /orders/**)를 기반으로 사전에 정의된 라우팅 테이블을 참조하여, 이 요청을 처리할 적절한 내부 마이크로서비스(예: order-service)로 프록시(Proxy)
  •  

기술적 장점

  • 관심사의 분리 (Separation of Concerns)
    • 비즈니스 로직을 처리하는 마이크로서비스 코드에서 인증/보안 관련 코드가 완전히 분리
    • 서비스 개발자는 보안 라이브러리나 Secret Key 관리에 신경 쓸 필요 없이 비즈니스 기능 개발에 집중
  • 중앙 집중화된 보안 관리
    • 보안 정책 변경(예: 토큰 만료 시간 변경, 암호화 알고리즘 교체)이 필요할 때, 여러 서비스를 수정할 필요 없이 API 게이트웨이 한 곳만 수정하면 됨
  • 보안 경계 형성 (Security Perimeter)
    • 외부와 내부 네트워크 사이에 명확한 보안 경계를 만들어, 인증되지 않은 어떤 요청도 내부 시스템에 도달하지 못하게 막는 방화벽 역할을 수행
  • 성능 향상
    • 다운스트림 서비스들이 매 요청마다 수행해야 할 암호화 검증 작업을 게이트웨이가 대신 처리해주므로, 전체 시스템의 부하를 줄임

2. 내부 JWT(서비스 간(Inter-Service) JWT 인증)

설명

  • 이 방식은 외부 사용자를 위한 인증과 별개로, 내부 마이크로서비스끼리 통신할 때 서로의 신원을 확인하기 위해 별도의 JWT를 사용하는 방법
  • 결국 클라이언트와 인증/인가 서비스는 또 따로 있어야 함
  • 중앙 인증 서비스(Auth Service)가 각 서비스에게 고유한 JWT를 발급하고, 서비스들은 다른 서비스를 호출할 때 이 JWT를 사용해 자신의 신원을 증명

과정

Step 1: 서비스 고유의 JWT 발급 요청 및 수신

  1. 블로그 서비스(Nest)가 시작될 때, 또는 주기적으로 중앙 인증 서비스(Spring Boot)에 자신의 서비스 이름(예: blog-service)과 같은 식별 정보를 보내 내부 통신용 JWT를 요청
  2. 인증 서비스는 요청한 서비스의 신원을 확인한 후, 해당 서비스만을 위한 내부용 JWT(Internal JWT)를 발급해 응답
    • 이 JWT에는 sub: 'blog-service' 와 같이 서비스의 이름이 포함
    • 사용자용 JWT보다 훨씬 짧은 만료 시간(예: 5분, 10분)을 가짐
    • 호출 가능한 서비스 목록(aud: ['user-service', 'payment-service']) 등 더 세분화된 권한 정보를 포함할 수 있음

Step 2: 내부 JWT를 이용한 서비스 간 호출

  1. 이제 블로그 서비스가 특정 유저 정보를 얻기 위해 회원 서비스(Spring Boot)를 호출해야 하는 상황을 가정
  2. 블로그 서비스는 회원 서비스를 호출할 때, Authorization: Bearer <내부용 JWT> 헤더에 Step 1에서 발급받은 내부용 JWT를 담아 보냄
    • 이때 API에서 받은 사용자 정보 헤더(예: X-User-ID: 123)도 함께 전달하여, "내가 블로그 서비스인데, 123번 사용자의 정보를 요청한다"는 의미를 명확히 밝힘

Step 3: 호출받은 서비스에서의 내부 JWT 검증

  1. 요청을 받은 회원 서비스는 Authorization 헤더의 내부용 JWT를 검증
  2. 이때 검증은 인증 서비스와 공유된 Secret Key 또는 Public Key를 사용
  3. JWT가 유효하고, 토큰에 명시된 sub 클레임이 신뢰할 수 있는 서비스(예: blog-service)임이 확인되면 요청을 처리
  4. 유효하지 않으면 403 Forbidden으로 응답하여 비인가 서비스의 접근을 차단

기술적 장점

  • Zero-Trust 네트워크 구현
    • "내부망은 안전하다"는 가정을 버리고, 모든 서비스 간 통신에 대해 인증을 강제하여 내부의 잠재적 위협으로부터 시스템을 보호
  • 세분화된 접근 제어
    • 서비스별로 호출할 수 있는 다른 서비스의 목록을 JWT에 명시하여, A 서비스는 B 서비스만 호출할 수 있고 C 서비스는 호출할 수 없도록 정교한 제어가 가능
  • 서비스 신원 명확화
    • 어떤 서비스가 요청했는지 명확하게 식별하고 로그로 남길 수 있어, 문제 발생 시 추적 및 디버깅이 용이
  • 게이트웨이 의존성 감소
    • API 게이트웨이가 모든 것을 처리하는 대신, 각 서비스가 자신의 보안을 일부 책임지는 구조로 분산되어 게이트웨이의 부하를 줄일 수 있음
반응형
Comments