Autenticação entre serviços
Além de autenticar solicitações de usuários finais, é recomendável autenticar serviços (usuários não humanos) que fazem solicitações à sua API. Nesta página, explicamos como usar contas de serviço para fornecer autenticação para pessoas ou serviços
Visão geral
Para identificar um serviço que envia solicitações para a API, use uma conta de serviço. O serviço de chamada usa a chave privada da conta de serviço para assinar um JSON Web Token (JWT) seguro e enviá-lo na solicitação para a API.
Para implementar a autenticação da conta de serviço na API e no serviço de chamada:
- Crie uma conta de serviço e uma chave que será usada pelo serviço de chamada.
- Adicione suporte para autenticação na configuração da API para o serviço de gateway de API.
Adicione o código ao serviço de chamada que:
- cria um JWT e o assina com a chave privada da conta de serviço;
- envia o JWT assinado em uma solicitação à API.
O gateway de API valida se as declarações no JWT correspondem à configuração na sua configuração de API antes de encaminhar a solicitação para sua API. O gateway de API não verifica as permissões do Cloud Identity concedidas na conta de serviço.
Pré-requisitos
Nesta página, presume-se que você já:
Criar uma conta de serviço com uma chave
Você precisa de uma conta de serviço com um arquivo de chave privada que o serviço de chamada usa para assinar o JWT. Se você tiver mais de um serviço enviando solicitações para sua API, crie uma conta de serviço para representar todos os serviços de chamada. Caso precise diferenciar os serviços crie uma conta de serviço e uma chave para cada serviço de chamada, eles podem ter permissões diferentes, por exemplo.
Esta seção mostra como usar o Google Cloud console e a gcloud
ferramenta de linha de comando para criar a conta de serviço e o arquivo de chave privada, e para
atribuir o papel
Criador de token de conta de serviço
à conta de serviço. Para informações sobre como executar essa tarefa usando uma API, consulte
Criar e gerenciar contas de serviço.
Para criar uma conta de serviço com uma chave:
Google Cloud Console do
Crie uma conta de serviço:
No Google Cloud console, acesse a página Criar conta de serviço.
Selecione um projeto.
No campo Nome da conta de serviço, insira um nome. O Google Cloud console dopreenche o campo ID da conta de serviço com base em esse nome.
Opcional: no campo Descrição da conta de serviço, digite uma descrição.
Clique em Criar.
Clique no campo Selecionar um papel.
Em Todos os papéis, selecione Conta de serviço > Criador do token da conta de serviço.
Clique em Continuar.
Clique em Concluído para terminar a criação da conta de serviço.
Não feche a janela do navegador. Você precisará usá-la no próximo procedimento.
Crie uma chave de conta de serviço:
- No Google Cloud console do, clique no endereço de e-mail da conta de serviço que você criou.
- Clique em Chaves.
- Clique em Adicionar chave e, depois, em Criar nova chave.
- Clique em Criar. O download de um arquivo de chave JSON é feito no seu computador.
- Clique em Fechar.
gcloud
É possível executar os comandos a seguir usando a Google Cloud CLI na máquina local ou no Cloud Shell.
Defina a conta padrão para
gcloud. Se você tiver mais de uma conta, escolha aquela que está no Google Cloud projeto que você quer usar.gcloud auth login
Mostre os IDs dos seus Google Cloud projetos.
gcloud projects list
Defina o projeto padrão. Substitua
PROJECT_IDpor o Google Cloud ID do projeto que você quer usar.gcloud config set project PROJECT_ID
Crie uma conta de serviço. Substitua
SA_NAMEeSA_DISPLAY_NAMEpelo nome e o nome de exibição que você quer usar.gcloud iam service-accounts create SA_NAME \ --display-name "SA_DISPLAY_NAME"
Liste o endereço de e-mail da conta de serviço recém-criada.
gcloud iam service-accounts list
Adicione o papel de criador do token de conta de serviço. Substitua
SA_EMAIL_ADDRESSpelo endereço de e-mail da conta de serviço.gcloud projects add-iam-policy-binding PROJECT_ID \ --member serviceAccount:SA_EMAIL_ADDRESS \ --role roles/iam.serviceAccountTokenCreator
Crie um arquivo de chave de conta de serviço no diretório de trabalho atual. Substitua
FILE_NAMEpelo nome escolhido para o arquivo de chaves. Por padrão, o comandogcloudcria um arquivo JSON.gcloud iam service-accounts keys create FILE_NAME.json \ --iam-account SA_EMAIL_ADDRESS
Consulte a
gcloud referência
para mais informações sobre os comandos anteriores.
Para informações sobre como proteger a chave privada, consulte Práticas recomendadas para gerenciar credenciais.
Configurar a API para oferecer suporte à autenticação
Ao criar uma configuração da API para seu gateway, você especifica uma conta de serviço que o gateway usa para interagir com outros serviços. Para ativar a autenticação de conta de serviço para serviços ligando seu gateway, modifique os objetos de segurança na configuração da API. As modificações vão variar de acordo com a versão da especificação OpenAPI usada.
Para configurar o gateway de API para validar as declarações no JWT assinado usado pelos serviços de chamada:
OpenAPI 2.0
- Adicione a conta de serviço como emissor na configuração da 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"
- Substitua
DEFINITION_NAMEpor uma string que identifica essa definição de segurança. É possível substituí-lo pelo nome da conta de serviço ou por um nome que identifique o serviço de chamada. - Substitua
SA_EMAIL_ADDRESSpelo endereço de e-mail da conta de serviço. - É possível definir várias definições de segurança na configuração da API, mas
cada uma delas precisa ter um
x-google-issuerdiferente. Caso tenha criado contas de serviço separadas para cada serviço de chamada, crie uma definição de segurança para cada uma conta de serviço, por exemplo: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"
- Substitua
- Se quiser, adicione
x-google-audiencesà seçãosecurityDefinitions. Se você não adicionarx-google-audiences, o gateway de API exigirá que a declaração"aud"(público-alvo) no JWT esteja no formatohttps://SERVICE_NAME, em que SERVICE_NAME é o nome do serviço de gateway de API, que você configurou no campohostdo documento da OpenAPI. - Adicione uma seção
securityno nível superior do arquivo (não recuada ou aninhada), a ser aplicada a toda a API, ou no nível dos métodos, a ser aplicada a um método específico. Se você usarsecurityseções no nível da API e do método, as configurações no nível do método modificarão as configurações no nível da API.security: - DEFINITION_NAME: []
- Substitua
DEFINITION_NAMEpelo nome usado na seçãosecurityDefinitions. - Se você tiver mais de uma definição na seção
securityDefinitions, adicione-as na seçãosecurity, por exemplo:security: - service-1: [] - service-2: []
- Substitua
- Implante sua configuração atualizada da API. Antes de encaminhar uma solicitação para sua API, o gateway de API verifica:
- a assinatura do JWT usando a chave pública, que está localizada no URI
especificado no campo
x-google-jwks_urino documento da OpenAPI; - se a declaração
"iss"(emissor) no JWT corresponde ao valor especificado nox-google-issuercampo; - se a declaração
"aud"(público) no JWT contém o nome do seu serviço do gateway de API ou corresponde a um dos valores especificados no campox-google-audiences; - se o token não expirou usando a declaração
"exp"(tempo de expiração).
- a assinatura do JWT usando a chave pública, que está localizada no URI
especificado no campo
OpenAPI 3.x
- Adicione a conta de serviço como emissor na configuração da API:
components: securitySchemes: SCHEME_NAME: type: oauth2 flows: implicit: authorizationUrl: "" scopes: {} x-google-auth: issuer: SA_EMAIL_ADDRESS jwksUri: https://www.googleapis.com/robot/v1/metadata/x509/SA_EMAIL_ADDRESS security: - SCHEME_NAME: []
- Substitua
SCHEME_NAMEpor uma string que identifica esse esquema de segurança. É possível substituí-lo pelo nome da conta de serviço ou por um nome que identifique o serviço de chamada. - Substitua
SA_EMAIL_ADDRESSpelo endereço de e-mail da conta de serviço. - É possível definir vários esquemas de segurança na configuração da API, mas
cada um deles precisa ter um
issuerdiferente. Caso tenha criado contas de serviço separadas para cada serviço de chamada, crie uma definição de segurança para cada uma conta de serviço, por exemplo:components: securitySchemes: service-1: type: oauth2 flows: implicit: authorizationUrl: "" scopes: {} x-google-auth: issuer: "service-1@example-project-12345.iam.gserviceaccount.com" jwksUri: https://www.googleapis.com/robot/v1/metadata/x509/service-1@example-project-12345.iam.gserviceaccount.com jwtLocations: - header: Authorization valuePrefix: "Bearer " service-2: type: oauth2 flows: implicit: authorizationUrl: "" scopes: {} x-google-auth: issuer: "service-2@example-project-12345.iam.gserviceaccount.com" jwksUri: "https://www.googleapis.com/robot/v1/metadata/x509/service-2@example-project-12345.iam.gserviceaccount.com"
- Substitua
- Se quiser, adicione
audiencesà seçãosecuritySchemes. Se você não adicionaraudiences, o gateway de API exigirá que a"aud"(público-alvo) declaração no JWT esteja no formatohttps://SERVICE_NAME, onde SERVICE_NAME é o nome do seu serviço de gateway de API, que você configurou no camposervers.urldo seu documento da OpenAPI. - Adicione uma seção
securityno nível superior do arquivo (não recuada ou aninhada), a ser aplicada a toda a API, ou no nível dos métodos, a ser aplicada a um método específico. Se você usarsecurityseções no nível da API e do método, as configurações no nível do método modificarão as configurações no nível da API.security: - SCHEME_NAME: []
- Substitua SCHEME_NAME pelo nome usado na seção
securitySchemes. - Se você tiver mais de uma definição na seção
securitySchemes, adicione-as na seçãosecurity, por exemplo:security: - service-1: [] - service-2: []
- Substitua SCHEME_NAME pelo nome usado na seção
- Implante sua configuração atualizada da API. Antes de encaminhar uma solicitação para sua API, o gateway de API verifica:
- a assinatura do JWT usando a chave pública, que está localizada no URI
especificado no
jwksUricampo no documento da OpenAPI; - se a declaração
"iss"(emissor) no JWT corresponde ao valor especificado noissuercampo; - se a declaração
"aud"(público) no JWT contém o nome do seu serviço do gateway de API ou corresponde a um dos valores especificados no campoaudiences; - se o token não expirou usando a declaração
"exp"(tempo de expiração).
- a assinatura do JWT usando a chave pública, que está localizada no URI
especificado no
Fazer uma solicitação autenticada para uma API do gateway de API
Para fazer uma solicitação autenticada, o serviço de chamada envia um JWT assinado pela conta de serviço especificada no documento OpenAPI. É preciso que o serviço de chamada:
- crie um JWT assinado com a chave privada da conta de serviço;
- envie o JWT assinado em uma solicitação à API.
O exemplo de código a seguir demonstra esse processo para idiomas selecionados. Para fazer uma solicitação autenticada em outros idiomas, consulte jwt.io para uma lista de bibliotecas compatíveis.
-
No serviço de chamada, adicione a seguinte função e transmita os seguintes
parâmetros:
Java -
saKeyfile: o caminho completo para o arquivo da chave privada da conta de serviço. -
saEmail: o endereço de e-mail da conta de serviço. -
audience: se você adicionou o campox-google-audiencesà configuração da API, definaaudiencecomo um dos valores especificados parax-google-audiences. Caso contrário, definaaudiencecomohttps://SERVICE_NAME, em queSERVICE_NAMEé o nome do serviço de gateway de API. -
expiryLength: o tempo de expiração do JWT, em segundos.
Python -
sa_keyfile: o caminho completo para o arquivo da chave privada da conta de serviço. -
sa_email: o endereço de e-mail da conta de serviço. -
audience: se você adicionou o campox-google-audiencesà configuração da API, definaaudiencecomo um dos valores especificados parax-google-audiences. Caso contrário, definaaudiencecomohttps://SERVICE_NAME, em queSERVICE_NAMEé o nome do serviço de gateway de API. -
expiry_length: o tempo de expiração do JWT, em segundos.
Go -
saKeyfile: o caminho completo para o arquivo da chave privada da conta de serviço. -
saEmail: o endereço de e-mail da conta de serviço. -
audience: se você adicionou o campox-google-audiencesà configuração da API, definaaudiencecomo um dos valores especificados parax-google-audiences. Caso contrário, definaaudiencecomohttps://SERVICE_NAME, em queSERVICE_NAMEé o nome do serviço de gateway de API. -
expiryLength: o tempo de expiração do JWT, em segundos.
A função cria um JWT e o assina usando o arquivo de chave privada. Em seguida, retorna o JWT assinado.
Java Python Go -
-
No serviço de chamada, adicione a seguinte função para enviar o JWT assinado
no
Authorization: Bearercabeçalho na solicitação para a API:Java Python Go
Ao enviar uma solicitação usando um JWT, por motivos de segurança, recomenda-se colocar o token de autenticação no cabeçalho Authorization: Bearer. Exemplo:
curl --request POST \ --header "Authorization: Bearer TOKEN" \ "GATEWAY_URL/hello"
Aqui, GATEWAY_URL e TOKEN precisam ser substituídos pelo URL do gateway implantado e pelo token de autenticação, respectivamente.
Receber resultados autenticados na API
O gateway de API geralmente encaminha todos os cabeçalhos recebidos. No entanto, ele substitui o cabeçalho Authorization original quando o endereço de back-end é especificado por x-google-backend na configuração da API.
O gateway de API enviará o resultado da autenticação no X-Apigateway-Api-Userinfo
para a API de back-end. É recomendável usar esse cabeçalho em vez do cabeçalho Authorization original. Esse cabeçalho está codificado em base64url e contém
o payload de JWT.