Autenticazione tra servizi

Puoi implementare l'autenticazione tra i servizi utilizzando un account di servizio in da un servizio gRPC. Questa pagina illustra l'autenticazione da servizio a servizio tramite che illustra un esempio completo, spiegando come configurare Extensible Service Proxy (ESP) in un servizio gRPC per supportare le richieste autenticate e per chiamare il servizio da un client gRPC.

Affinché qualsiasi servizio effettui chiamate autenticate in Cloud Endpoints API, il servizio chiamante deve avere un account di servizio e deve inviare un token di autenticazione nella chiamata. Il chiamante deve utilizzare un Token ID Google o un modello personalizzato JSON Web Token (JWT) firmato solo dall'account di servizio del chiamante. ESP verifica che L'attestazione iss nel JWT corrisponde all'impostazione issuer nel servizio configurazione. ESP non verifica se è presente Identity and Access Management autorizzazioni concesse all'account di servizio.

Nel nostro esempio, configuri e utilizzi la forma più semplice di Service-to-Service dell'autenticazione, in cui il client utilizza il proprio account di servizio Google Cloud per per generare JWT di autenticazione. L'approccio per altri metodi di autenticazione è simile, anche se il processo lato client per ottenere un'autenticazione valida dipende dal metodo di autenticazione utilizzato.

Prima di iniziare

Questa guida si basa sull'esempio della libreria utilizzato nelle nostre Tutorial.

  1. Clona il repository git in cui è ospitato il codice di esempio gRPC:

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
    
  2. Cambia la directory di lavoro:

    cd python-docs-samples/endpoints/bookstore-grpc/
    
  3. Segui le istruzioni nella Tutorial per configurare un progetto, se non ne hai già uno.

In questo esempio, utilizzi il deployment in Google Kubernetes Engine, anche se la configurazione di autenticazione è la stessa di Compute Engine.

Nell'esempio, sono presenti due progetti Google Cloud Platform a cui viene fatto riferimento:

  • Il progetto producer di servizi, ossia il progetto proprietario del Cloud Endpoints per il servizio gRPC.
  • Il progetto consumer di servizio, ovvero il progetto proprietario della gRPC di alto profilo.

Creazione dell'account di servizio consumer e della chiave

Per creare l'account di servizio e la chiave per il progetto consumer:

  1. Nella console Google Cloud, vai ad API e i servizi di machine learning.

    API e

    Assicurati di essere nel tuo progetto consumer.
  2. Nella pagina Credenziali, nell'elenco a discesa Crea credenziali, Seleziona Service Account Key (Chiave account di servizio).
  3. Nella pagina Crea chiave account di servizio, se disponi di un servizio esistente che vuoi utilizzare, selezionalo. Altrimenti, nel Nell'elenco a discesa Account di servizio, seleziona Nuovo account di servizio e digita un nome account.

    Viene creato automaticamente un ID account di servizio corrispondente. Prendi nota ID, poiché è necessario nelle sezioni seguenti. Ad esempio:

    service-account-name@YOUR_PROJECT_ID.iam.gserviceaccount.com
    
  4. Fai clic sull'elenco a discesa Ruolo e seleziona i ruoli seguenti:

    • Account di servizio > Utente account di servizio
    • Account di servizio > Creatore token account di servizio
  5. Assicurati che sia selezionato il tipo di chiave JSON.

  6. Fai clic su Crea. Il file della chiave JSON dell'account di servizio viene scaricato dalla macchina locale. Prendi nota della posizione e assicurati che sia archiviata in modo sicuro viene utilizzato in un secondo momento per generare token.

Configurazione dell'autenticazione per il servizio

Utilizza il progetto producer per tutti i passaggi di questa sezione.

Imposta l'autenticazione nella configurazione dell'API gRPC

L'autenticazione per ESP è configurata in authentication del tuo file YAML di configurazione API gRPC. La configurazione con l'autenticazione per questo servizio di esempio è api_config_auth.yaml

authentication:
  providers:
  - id: google_service_account
    # Replace SERVICE-ACCOUNT-ID with your service account's email address.
    issuer: SERVICE-ACCOUNT-ID
    jwks_uri: https://www.googleapis.com/robot/v1/metadata/x509/SERVICE-ACCOUNT-ID
  rules:
  # This auth rule will apply to all methods.
  - selector: "*"
    requirements:
      - provider_id: google_service_account

La sezione providers specifica i provider di autenticazione a cui vuoi in questo caso vuoi usare un account di servizio Google come o un provider di autenticazione. La sezione rules specifica che sono necessari token di questo provider per accedere a tutti i metodi del tuo servizio.

Nella tua copia di questo file dal repository clonato:

  • Sostituisci MY_PROJECT_ID con l'ID del tuo progetto producer.
  • Modifica SERVICE-ACCOUNT-ID nella sezione authentication (sia in issuer e jwks_uri) all'ID account di servizio consumer che hai annotato. nella sezione precedente. Questo indica a ESP che vuoi concedere l'accesso al servizio agli utenti che forniscono token validi da questo un particolare account di servizio.
  • Se vuoi, aggiungi jwt_locations sotto l'elemento providers. Puoi utilizzare questo valore per definire una località JWT personalizzata. Le località JWT predefinite sono i metadati Authorization (precedenti con "Bearer ") e i metadati X-Goog-Iap-Jwt-Assertion.

Salva il file per il passaggio successivo.

Esegui il deployment della configurazione e del servizio

Questi passaggi sono gli stessi di Introduzione a gRPC su GKE:

  1. Esegui il deployment della configurazione del servizio in Endpoints: devi eseguire questa operazione anche se l'hai fatto per il tutorial, poiché si tratta di un configurazione diversa. Prendi nota del nome del servizio restituito:

    gcloud endpoints services deploy api_descriptor.pb api_config_auth.yaml --project PRODUCER_PROJECT
    
  2. Crea un cluster di container e autenticare kubectl nel cluster, se non l'hai ancora fatto.

  3. Esegui il deployment dell'API e di ESP di esempio nel cluster. Se utilizzi progetti separati per producer e consumer, assicurati innanzitutto di aver impostato il progetto appropriato nella riga di comando gcloud. questo strumento:

    gcloud config set project PRODUCER_PROJECT
    

Chiamata a metodi autenticati da un client gRPC

Infine, sul lato client, puoi utilizzare la chiave dell'account di servizio per generare JWT, quindi utilizzalo per chiamare un metodo Bookstore autenticato. Installa innanzitutto i requisiti Python appropriati per generare il token e eseguire il client di esempio. Assicurati di essere nel python-docs-samples/endpoints/bookstore-grpc cartella del client clonato, quindi:

virtualenv bookstore-env
source bookstore-env/bin/activate
pip install -r requirements.txt

Genera un token JWT

In questo esempio, la Libreria utilizza l'autenticazione service-to-service in cui servizio chiamante è puramente autenticato dal suo account di servizio, quindi la creazione un token appropriato da inviare con le nostre richieste è semplice. Tieni presente che puoi anche richiedono un'autenticazione service-to-service più rigorosa quando deve essere ulteriormente autenticato da Google (utilizzando token ID Google).

Per questo esempio, lo script Python fornito può generare un token dal file JSON chiave scaricato in precedenza, utilizzando un indirizzo email e un ID utente fittizio.

#!/usr/bin/env python

# Copyright 2016 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Example of generating a JWT signed from a service account file."""

import argparse
import json
import time

import google.auth.crypt
import google.auth.jwt

"""Max lifetime of the token (one hour, in seconds)."""
MAX_TOKEN_LIFETIME_SECS = 3600


def generate_jwt(service_account_file, issuer, audiences):
    """Generates a signed JSON Web Token using a Google API Service Account."""
    with open(service_account_file) as fh:
        service_account_info = json.load(fh)

    signer = google.auth.crypt.RSASigner.from_string(
        service_account_info["private_key"], service_account_info["private_key_id"]
    )

    now = int(time.time())

    payload = {
        "iat": now,
        "exp": now + MAX_TOKEN_LIFETIME_SECS,
        # aud must match 'audience' in the security configuration in your
        # swagger spec. It can be any string.
        "aud": audiences,
        # iss must match 'issuer' in the security configuration in your
        # swagger spec. It can be any string.
        "iss": issuer,
        # sub and email are mapped to the user id and email respectively.
        "sub": issuer,
        "email": "user@example.com",
    }

    signed_jwt = google.auth.jwt.encode(signer, payload)
    return signed_jwt


if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
    )
    parser.add_argument("--file", help="The path to your service account json file.")
    parser.add_argument("--issuer", default="", help="issuer")
    parser.add_argument("--audiences", default="", help="audiences")

    args = parser.parse_args()

    signed_jwt = generate_jwt(args.file, args.issuer, args.audiences)
    print(signed_jwt.decode("utf-8"))

Per generare un token utilizzando lo script:

  • Genera un token JWT e assegnalo alla variabile $JWT_TOKEN:

    JWT_TOKEN=$(python jwt_token_gen.py \
        --file=[SERVICE_ACCOUNT_FILE] \
        --audiences=[SERVICE_NAME] \
        --issuer=[SERVICE-ACCOUNT-ID])
    

    dove:

    • [SERVICE_ACCOUNT_FILE] è il file JSON dell'account di servizio consumer scaricato chiave.
    • [SERVICE_NAME] è il nome del servizio Libreria che è stato restituito quando hai eseguito il deployment della configurazione aggiornata del servizio Endpoint.
    • [SERVICE-ACCOUNT-ID] è l'ID completo dell'account di servizio consumer quando generato l'account di servizio.

Effettua una chiamata gRPC autenticata

In quest'ultimo passaggio bookstore_client.py, che è lo stesso client utilizzato Tutorial. Per effettuare una chiamata autenticata, il cliente trasmette il JWT metadata con i relativi .

def run(
    host, port, api_key, auth_token, timeout, use_tls, servername_override, ca_path

Per eseguire l'esempio:

  1. Usa kubectl get services per ottenere l'indirizzo IP esterno dell'oggetto di cui è stato eseguito il deployment Libreria:

    #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
    

    In questo caso, si tratta del servizio esp-grpc-bookstore e il suo IP esterno è 104.196.60.37.

  2. Assegna l'indirizzo IP alla variabile EXTERNAL_IP

    EXTERNAL_IP=104.196.60.37
    
  3. Elenca tutti gli scaffali del servizio Libreria:

    python bookstore_client.py --port=80 --host=$EXTERNAL_IP --auth_token=$JWT_TOKEN
    

    Il servizio restituisce tutti gli scaffali della libreria corrente. Puoi raddoppiare Controllalo non fornendo un token o specificando l'account di servizio errato ID durante la generazione del JWT. Il comando non dovrebbe riuscire.

Passaggi successivi