gRPC 서비스에서 서비스 계정을 사용하여 서비스 간 인증을 구현할 수 있습니다. 이 페이지에서는 gRPC 서비스에서 Extensible Service Proxy(ESP)를 구성하여 인증된 요청을 지원하는 방법과 gRPC 클라이언트에서 서비스를 호출하는 방법 등 전체적인 예를 통해 서비스 간 인증 과정을 보여줍니다.
모든 서비스에서 Cloud Endpoints API에 인증 호출을 실행하려면 호출 서비스에 서비스 계정이 있어야 하고 호출 시 호출 서비스가 인증 토큰을 전송해야 합니다. 호출자는 호출자 서비스 계정으로 서명된 Google ID 토큰 또는 커스텀 JSON 웹 토큰(JWT)만 사용해야 합니다. ESP는 JWT의 iss
클레임이 서비스 구성의 issuer
설정과 일치하는지 검증합니다. ESP는 서비스 계정에 부여된 ID 및 액세스 관리 권한을 확인하지 않습니다.
이 예시에서는 클라이언트가 Google Cloud 서비스 계정을 사용하여 인증 JWT를 생성하는 가장 간단한 형태의 서비스 간 인증을 설정하고 사용합니다. 다른 인증 방법도 이와 유사하지만 유효한 인증 토큰을 얻기 위한 클라이언트 측 과정은 사용되는 인증 방식에 따라 다릅니다.
시작하기 전에
이 가이드에서는 Google의 가이드에서 사용한 Bookstore의 예를 사용합니다.
gRPC 예시 코드가 호스팅되는 Git 저장소를 복제합니다.
git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
작업 디렉터리를 변경합니다.
cd python-docs-samples/endpoints/bookstore-grpc/
아직 프로젝트가 없다면 가이드의 안내에 따라 프로젝트를 만듭니다.
이 예에서는 Google Kubernetes Engine 배포를 사용하지만 인증 설정은 Compute Engine에서도 동일합니다.
이 예에서는 두 개의 Google Cloud Platform 프로젝트가 언급됩니다.
- gRPC 서비스용 Cloud Endpoints를 소유하는 프로젝트인 서비스 생산자 프로젝트
- gRPC 클라이언트를 소유하는 프로젝트인 서비스 소비자 프로젝트
소비자 서비스 계정과 키 만들기
소비자 프로젝트용 서비스 계정과 키를 만들려면 다음 안내를 따르세요.
- Google Cloud 콘솔에서 API 및 서비스로 이동합니다. 현재 위치가 소비자 프로젝트인지 확인합니다.
- 사용자 인증 정보 페이지의 사용자 인증 정보 만들기 드롭다운 목록에서 서비스 계정 키를 선택합니다.
서비스 계정 키 만들기 페이지에 사용하려는 기존 서비스 계정이 있다면 해당 계정을 선택합니다. 그렇지 않다면 서비스 계정 드롭다운 목록에서 새 서비스 계정을 선택하고 계정 이름을 입력합니다.
해당 서비스 계정 ID가 생성됩니다. 다음 섹션에서 필요하기 때문에 ID를 적어둡니다. 예를 들면 다음과 같습니다.
service-account-name@YOUR_PROJECT_ID.iam.gserviceaccount.com
역할 드롭다운 목록을 클릭하고 다음 역할을 선택합니다.
- 서비스 계정 > 서비스 계정 사용자
- 서비스 계정 > 서비스 계정 토큰 생성자
JSON 키 유형이 선택되었는지 확인합니다.
만들기를 클릭합니다. 서비스 계정 JSON 키 파일이 로컬 머신에 다운로드됩니다. 나중에 토큰을 생성할 때 사용해야 하므로 해당 위치를 확인하고 안전하게 저장되었는지 확인합니다.
서비스를 위한 인증 구성
이 섹션의 모든 단계에서 생산자 프로젝트를 사용합니다.
gRPC API 구성에 인증 설정
ESP 인증은 gRPC API 구성 YAML 파일의 authentication
섹션에서 구성됩니다. 이 예시 서비스의 인증 구성은 api_config_auth.yaml
에 있습니다.
providers
섹션은 사용할 인증 공급자를 지정합니다. 이 경우에는 Google 서비스 계정을 인증 공급자로 사용하려 한다고 지정합니다. rules
섹션은 모든 서비스 메서드에 액세스하기 위해 이 공급자의 토큰이 필요하다고 지정합니다.
클론된 저장소에 있는 이 파일 사본에서 다음을 수행하세요.
MY_PROJECT_ID
를 생산자 프로젝트 ID로 변경합니다.authentication
섹션에서SERVICE-ACCOUNT-ID
를 이전 단계에서 적어둔 소비자 서비스 계정 ID로 변경합니다(issuer
값과jwks_uri
값 모두에서). 이렇게 하면 이 특정 서비스 계정의 유효한 토큰을 제공하는 사용자에게 서비스 액세스 권한이 부여된다는 것을 ESP에서 알 수 있습니다.- 선택사항으로
providers
요소 아래에jwt_locations
를 추가합니다. 이 값을 사용하여 커스텀 JWT 위치를 정의할 수 있습니다. 기본 JWT 위치는Authorization
메타데이터('Bearer' 프리픽스가 붙음) 및X-Goog-Iap-Jwt-Assertion
메타데이터입니다.
다음 단계를 위해 파일을 저장합니다.
구성 및 서비스 배포
아래의 단계는 GKE에서 gRPC 시작하기와 동일합니다.
서비스 구성을 Endpoints에 배포: 튜토리얼에서 이 과정을 이미 수행했더라도 이것은 다른 구성이기 때문에 이 작업을 수행해야 합니다. 반환되는 서비스 이름을 적어둡니다.
gcloud endpoints services deploy api_descriptor.pb api_config_auth.yaml --project PRODUCER_PROJECT
컨테이너 클러스터를 만들고 아직 인증하지 않았다면
kubectl
을 클러스터에 인증합니다.샘플 API 및 ESP를 클러스터에 배포합니다. 생산자 프로젝트와 소비자 프로젝트를 별도로 사용하는 경우 먼저
gcloud
명령줄 도구 내에 적절한 프로젝트를 설정했는지 확인합니다.gcloud config set project PRODUCER_PROJECT
gRPC 클라이언트에서 인증된 메서드 호출
마지막으로 클라이언트 측에서 서비스 계정 키를 사용하여 JWT 토큰을 생성한 후에 토큰을 사용하여 인증된 Bookstore 메서드를 호출할 수 있습니다.
먼저 적절한 Python 요구사항을 설치하여 토큰을 생성하고 예시 클라이언트를 실행해야 합니다. 현재 위치가 클론된 클라이언트의 python-docs-samples/endpoints/bookstore-grpc
폴더인지 확인하고 다음을 수행합니다.
virtualenv bookstore-env
source bookstore-env/bin/activate
pip install -r requirements.txt
JWT 토큰 생성
이 예에서 Bookstore는 호출 서비스가 서비스 계정으로만 인증되는 서비스 간 인증을 사용하므로 요청과 함께 전송할 적절한 토큰을 간편하게 만들 수 있습니다. 생성된 토큰을 Google에서 추가로 인증해야 하는 경우(Google ID 토큰을 사용하여) 더 엄격한 서비스 간 인증을 요구할 수도 있습니다.
이 예시에 나와 있는 Python 스크립트는 더미 사용자 ID와 이메일을 사용하여 앞에서 다운로드한 JSON 키 파일로 토큰을 생성할 수 있습니다.
스크립트를 사용하여 토큰을 생성하려면 다음 안내를 따르세요.
JWT 토큰을 생성하여
$JWT_TOKEN
변수에 할당합니다.JWT_TOKEN=$(python jwt_token_gen.py \ --file=[SERVICE_ACCOUNT_FILE] \ --audiences=[SERVICE_NAME] \ --issuer=[SERVICE-ACCOUNT-ID])
각 항목의 의미는 다음과 같습니다.
[SERVICE_ACCOUNT_FILE]
은 다운로드한 소비자 서비스 계정 JSON 키 파일입니다.[SERVICE_NAME]
은 업데이트된 서비스 구성을 Endpoints에 배포했을 때 반환된 Bookstore 서비스의 이름입니다.[SERVICE-ACCOUNT-ID]
는 서비스 계정을 생성했을 때의 전체 소비자 서비스 계정 ID입니다.
인증된 gRPC 호출 실행
이 마지막 단계에서는 가이드에서 사용한 것과 동일한 클라이언트인 bookstore_client.py
를 사용합니다. 인증된 호출을 실행하기 위해 클라이언트가 JWT를 메타데이터로 메서드 호출과 함께 전달합니다.
이 예시를 실행하려면 다음 안내를 따르세요.
kubectl get services
를 사용하여 배포된 Bookstore의 외부 IP 주소를 가져옵니다.#kubectl get services NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE echo 10.11.246.240 104.196.186.92 80/TCP 10d endpoints 10.11.243.168 104.196.210.50 80/TCP,8090/TCP 10d esp-grpc-bookstore 10.11.254.34 104.196.60.37 80/TCP 1d kubernetes 10.11.240.1 <none> 443/TCP 10d
이 경우에는
esp-grpc-bookstore
서비스이고 외부 IP는104.196.60.37
입니다.IP 주소를
EXTERNAL_IP
변수에 할당합니다.EXTERNAL_IP=104.196.60.37
Bookstore 서비스의 모든 실행기를 나열합니다.
python bookstore_client.py --port=80 --host=$EXTERNAL_IP --auth_token=$JWT_TOKEN
이 서비스는 현재 Bookstore에 있는 모든 실행기를 반환합니다. 토큰을 제공하지 않거나 JWT를 생성할 때 엉뚱한 서비스 계정 ID를 지정하여 다시 한 번 확인할 수 있습니다. 명령어가 실패합니다.