서비스 간 인증
최종 사용자 요청을 인증하는 것 외에도 API에 요청을 수행하는 서비스(비인간 사용자)를 인증해야 할 수 있습니다. 이 페이지에서는 서비스 계정을 사용해서 인간 또는 서비스에 대해 인증을 제공하는 방법을 설명합니다.
개요
API에 요청을 보내는 서비스를 식별하려면 서비스 계정을 사용합니다. 호출하는 서비스는 서비스 계정의 비공개 키를 사용하여 보안 JSON 웹 토큰(JWT)에 서명하고, 서명된 JWT를 요청에 포함하여 API에 보냅니다.
API 및 호출 서비스에서 서비스 계정 인증을 구현하려면 다음 안내를 따르세요.
- 호출 서비스에서 사용할 서비스 계정과 키를 만듭니다.
- API 게이트웨이 서비스에 대해 API 구성에 인증 지원을 추가합니다.
호출 서비스에 다음과 같은 코드를 추가합니다.
- JWT를 만들고 이를 서비스 계정의 비공개 키로 서명합니다.
- 서명된 JWT를 API에 대한 요청에 포함하여 전송합니다.
API 게이트웨이는 요청을 API로 전달하기 전 JWT의 클레임이 API 구성 내용과 일치하는지 확인합니다. API 게이트웨이는 서비스 계정에 부여한 Cloud Identity 권한을 확인하지 않습니다.
기본 요건
이 페이지에서는 다음 작업을 이미 완료했다고 가정합니다.
키가 있는 서비스 계정 만들기
호출 서비스의 JWT 서명을 위한 비공개 키 파일을 보유한 서비스 계정이 필요합니다. API에 요청을 보내는 서비스가 두 개 이상이면 이 호출 서비스를 모두 포함하는 하나의 서비스 계정을 만들 수 있습니다. 서비스를 구분해야 하는 경우(예를 들어 서비스마다 사용 권한이 다른 경우) 호출 서비스별로 서비스 계정과 키를 만들 수 있습니다.
이 섹션에서는 Google Cloud Console 및 gcloud
명령줄 도구를 사용하여 서비스 계정 및 비공개 키 파일을 만들고 서비스 계정을 서비스 계정 토큰 작성기 역할에 할당하는 방법을 보여줍니다. API를 사용하여 이 작업을 수행하는 방법에 대한 자세한 내용은 서비스 계정 만들기 및 관리를 참조하세요.
키가 있는 서비스 계정을 만들려면 다음 안내를 따르세요.
Google Cloud 콘솔
서비스 계정을 만듭니다.
Google Cloud 콘솔에서 서비스 계정 만들기로 이동합니다.
프로젝트를 선택합니다.
서비스 계정 이름 필드에 이름을 입력합니다. Google Cloud 콘솔은 이 이름을 기반으로 서비스 계정 ID 필드를 채웁니다.
선택사항: 서비스 계정 설명 필드에 설명을 입력합니다.
만들기를 클릭합니다.
역할 선택 필드를 클릭합니다.
모든 역할에서 서비스 계정 > 서비스 계정 토큰 생성자를 선택합니다.
계속을 클릭합니다.
완료를 클릭하여 서비스 계정 만들기를 마칩니다.
브라우저 창을 닫지 마세요. 다음 절차에서 사용합니다.
서비스 계정 키를 만듭니다.
- Google Cloud 콘솔에서 자신이 만든 서비스 계정의 이메일 주소를 클릭합니다.
- 키를 클릭합니다.
- 키 추가를 클릭한 후 새 키 만들기를 클릭합니다.
- 만들기를 클릭합니다. JSON 키 파일이 컴퓨터에 다운로드됩니다.
- 닫기를 클릭합니다.
gcloud
로컬 머신이나 Cloud Shell 내에서 Google Cloud CLI를 사용하여 다음 명령어를 실행할 수 있습니다.
gcloud
에 기본 계정을 설정합니다. 계정이 2개 이상이면 사용하려는 Google Cloud 프로젝트에 있는 계정을 선택해야 합니다.gcloud auth login
Google Cloud 프로젝트의 프로젝트 ID를 표시합니다.
gcloud projects list
기본 프로젝트를 설정합니다.
PROJECT_ID
를 사용하려는 Google Cloud 프로젝트 ID로 바꿉니다.gcloud config set project PROJECT_ID
서비스 계정 만들기
SA_NAME
과SA_DISPLAY_NAME
을 사용하려는 이름과 표시 이름으로 바꿉니다.gcloud iam service-accounts create SA_NAME \ --display-name "SA_DISPLAY_NAME"
방금 만든 서비스 계정의 이메일 주소를 표시합니다.
gcloud iam service-accounts list
서비스 계정 토큰 생성자 역할을 추가합니다.
SA_EMAIL_ADDRESS
를 서비스 계정의 이메일 주소로 바꿉니다.gcloud projects add-iam-policy-binding PROJECT_ID \ --member serviceAccount:SA_EMAIL_ADDRESS \ --role roles/iam.serviceAccountTokenCreator
현재 작업 디렉터리에 서비스 계정 키 파일을 만듭니다.
FILE_NAME
을 키 파일에 사용할 이름으로 바꿉니다.gcloud
명령어가 JSON 파일을 생성하는 것이 기본 설정입니다.gcloud iam service-accounts keys create FILE_NAME.json \ --iam-account SA_EMAIL_ADDRESS
앞에 나온 명령어에 대한 자세한 내용은 gcloud
참조 문서를 확인하세요.
비공개 키 보호에 대한 자세한 내용은 사용자 인증 정보 관리 권장사항을 참조하세요.
인증을 지원하도록 API 구성
게이트웨이에 대해 API 구성을 만들 때는 다른 서비스와 상호 작용하기 위해 게이트웨이에 사용되는 서비스 계정을 지정합니다. 게이트웨이를 호출하는 서비스에 대해 서비스 계정 인증을 사용 설정하려면 API 구성에서 보안 요구사항 객체 및 보안 정의 객체를 수정합니다. 아래 단계를 수행하면 호출 서비스에 사용되는 서명된 JWT에서 클레임을 검증하도록 API 게이트웨이가 사용 설정됩니다.
API 구성에서 서비스 계정을 발급기관으로 추가합니다.
securityDefinitions: DEFINITION_NAME: authorizationUrl: "" flow: "implicit" type: "oauth2" x-google-issuer: "SA_EMAIL_ADDRESS" x-google-jwks_uri: "https://www.googleapis.com/robot/v1/metadata/x509/SA_EMAIL_ADDRESS"
DEFINITION_NAME
을 이 보안 정의를 식별하는 문자열로 바꿉니다. 서비스 계정 이름 또는 호출 서비스를 식별하는 이름으로 바꿀 수 있습니다.SA_EMAIL_ADDRESS
를 서비스 계정의 이메일 주소로 바꿉니다.- API 구성에 여러 보안 설정을 정의할 수 있지만 각 정의에 포함되는
x-google-issuer
는 서로 달라야 합니다. 호출 서비스마다 별도의 서비스 계정을 만들었으면 서비스 계정마다 보안 정의를 만들 수 있습니다. 예를 들면 다음과 같습니다.
securityDefinitions: service-1: authorizationUrl: "" flow: "implicit" type: "oauth2" x-google-issuer: "service-1@example-project-12345.iam.gserviceaccount.com" x-google-jwks_uri: "https://www.googleapis.com/robot/v1/metadata/x509/service-1@example-project-12345.iam.gserviceaccount.com" service-2: authorizationUrl: "" flow: "implicit" type: "oauth2" x-google-issuer: "service-2@example-project-12345.iam.gserviceaccount.com" x-google-jwks_uri: "https://www.googleapis.com/robot/v1/metadata/x509/service-2@example-project-12345.iam.gserviceaccount.com"
선택사항으로
x-google-audiences
를securityDefinitions
섹션에 추가합니다.x-google-audiences
를 추가하지 않은 경우 API 게이트웨이에서는 JWT의"aud"
(대상) 클레임이https://SERVICE_NAME
형식이어야 합니다. 여기서 SERVICE_NAME은 API 게이트웨이 서비스의 이름이며, OpenAPI 문서의host
필드에 구성한 것입니다.security
섹션을 파일의 최상위 수준(들여쓰거나 중첩하지 않음)에서 추가하여 전체 API에 적용하거나 메서드 수준에서 추가하여 특정 메서드에 적용합니다. API 및 메서드 수준 모두에security
섹션을 사용하는 경우에는 메서드 수준 설정이 API 수준 설정보다 우선 적용됩니다.security: - DEFINITION_NAME: []
DEFINITION_NAME
을securityDefinitions
섹션에 사용한 이름으로 바꿉니다.securityDefinitions
섹션에 정의가 둘 이상 있는 경우security
섹션에 이를 추가합니다. 예를 들면 다음과 같습니다.security: - service-1: [] - service-2: []
업데이트된 API 구성을 배포합니다.
API 게이트웨이는 요청을 API로 전달하기 전에 다음을 확인합니다.
- 공개 키를 사용한 JWT의 서명이 API 구성의
x-google-jwks_uri
필드에 지정된 URI에 있는지 확인합니다. - JWT의
"iss"
(발급기관) 클레임이x-google-issuer
필드에 지정된 값과 일치하는지 확인합니다. - JWT의
"aud"
(대상) 클레임이 API 게이트웨이 서비스 이름에 포함되었는지,x-google-audiences
필드에서 지정한 값 중 하나와 일치하는지 확인합니다. "exp"
(만료 시간) 클레임을 사용하여 토큰이 만료되었는지 확인합니다.
x-google-issuer
, x-google-jwks_uri
, x-google-audiences
에 대한 자세한 내용은 OpenAPI 확장 프로그램을 참조하세요.
API 게이트웨이 API에 인증된 요청 수행
인증된 요청을 위해서는 API 구성에 지정한 서비스 계정으로 서명된 JWT를 호출 서비스에서 보내야 합니다. 호출 서비스는 다음을 수행해야 합니다.
- JWT를 만들고 이를 서비스 계정의 비공개 키로 서명합니다.
- 서명된 JWT를 API에 대한 요청에 포함하여 전송합니다.
다음 샘플 코드는 특정 언어에 대한 이 프로세스를 보여줍니다. 다른 언어로 인증된 요청을 수행하려면 jwt.io를 참조하여 지원되는 라이브러리 목록을 확인하세요.
-
호출 서비스에서 다음 함수를 추가하고 이를 다음 매개변수에 전달합니다.
자바 saKeyfile
: 서비스 계정의 비공개 키 파일에 대한 전체 경로입니다.-
saEmail
: 서비스 계정의 이메일 주소입니다. -
audience
:x-google-audiences
필드를 API 구성에 추가한 경우audience
를x-google-audiences
에 지정한 값 중 하나로 설정합니다. 그 이외에는audience
를https://SERVICE_NAME
으로 설정합니다. 여기에서SERVICE_NAME
은 API 게이트웨이 서비스 이름입니다. expiryLength
: JWT 만료 시간(초)입니다.
Python -
sa_keyfile
: 서비스 계정의 비공개 키 파일에 대한 전체 경로입니다. -
sa_email
: 서비스 계정의 이메일 주소입니다. -
audience
:x-google-audiences
필드를 API 구성에 추가한 경우audience
를x-google-audiences
에 지정한 값 중 하나로 설정합니다. 그 이외에는audience
를https://SERVICE_NAME
으로 설정합니다. 여기에서SERVICE_NAME
은 API 게이트웨이 서비스 이름입니다. expiry_length
: JWT 만료 시간(초)입니다.
Go saKeyfile
: 서비스 계정의 비공개 키 파일에 대한 전체 경로입니다.-
saEmail
: 서비스 계정의 이메일 주소입니다. -
audience
:x-google-audiences
필드를 API 구성에 추가한 경우audience
를x-google-audiences
에 지정한 값 중 하나로 설정합니다. 그 이외에는audience
를https://SERVICE_NAME
으로 설정합니다. 여기에서SERVICE_NAME
은 API 게이트웨이 서비스 이름입니다. expiryLength
: JWT 만료 시간(초)입니다.
이 함수는 JWT를 만들고 비공개 키 파일을 사용하여 이에 서명한 다음, 서명된 JWT를 반환합니다.
자바 Python Go - 호출 서비스에서 다음 함수를 추가해서 API에 대한 요청의
Authorization: Bearer
헤더에 서명된 JWT를 보냅니다.자바 Python Go
JWT를 사용하여 요청을 보낼 때는 보안상의 이유로 Authorization: Bearer
헤더에 인증 토큰을 포함하는 것이 좋습니다. 예를 들면 다음과 같습니다.
curl --request POST \ --header "Authorization: Bearer ${TOKEN}" \ "${GATEWAY_URL}/echo"
여기서 GATEWAY_URL
와 TOKEN
은 각각 배포된 게이트웨이 URL 및 인증 토큰을 포함하는 환경 변수입니다.
API에서 인증 결과 수신
API 게이트웨이는 수신하는 모든 헤더를 전달합니다. 하지만 API 구성에서 백엔드 주소가 x-google-backend
로 지정된 경우 원래 Authorization
헤더를 재정의합니다.
API 게이트웨이는 X-Apigateway-Api-Userinfo
의 인증 결과를 백엔드 API에 전송합니다. 원래 Authorization
헤더 대신 이 헤더를 사용하는 것이 좋습니다. 이 헤더는 base64url
로 인코딩되며 JWT 페이로드를 포함합니다.