Como configurar a autenticação em aplicativos de produção de servidor para servidor

Neste guia, você aprende a configurar a autenticação e autorização em aplicativos de produção, de servidor para servidor. Autenticação refere-se ao processo de determinação da identidade de um cliente. Autorização refere-se ao processo de determinação das permissões que um cliente autenticado tem em um conjunto de recursos. Ou seja, a autenticação identifica quem você é e a autorização determina o que você pode fazer. Para mais informações sobre métodos de autenticação compatíveis e como escolhê-los, consulte visão geral de autenticação.

O Google usa credenciais para identificar seu aplicativo para cota e faturamento. Suas credenciais também são usadas para autorizar o acesso às APIs, aos recursos e funcionalidades do GCP.

Como fornecer credenciais para seu aplicativo

As bibliotecas de cliente do GCP usam uma estratégia chamada Application Default Credentials (ADC) para encontrar as credenciais do seu aplicativo. Quando seu código usa uma biblioteca de cliente, suas credenciais são verificadas pelo ADC na seguinte ordem:

  1. Primeiro, o ADC verifica se a variável de ambiente GOOGLE_APPLICATION_CREDENTIALS está configurada. Em caso afirmativo, o arquivo da conta do serviço apontado pela variável é usado.

  2. Se a variável não estiver configurada, o ADC usará a conta de serviço padrão fornecida pelo Compute Engine, Kubernetes Engine, App Engine e Cloud Functions para aplicativos executados nesses serviços.

  3. Caso o ADC não use nenhuma das credenciais acima, ocorre um erro.

No exemplo de código abaixo, essa estratégia é ilustrada. As credenciais do aplicativo não são especificadas explicitamente. No entanto, o ADC consegue encontrar as credenciais, desde que a variável de ambiente GOOGLE_APPLICATION_CREDENTIALS esteja configurada, ou o aplicativo esteja em execução no Compute Engine, Kubernetes Engine, App Engine ou Cloud Functions.

C#

public object AuthImplicit(string projectId)
{
    // If you don't specify credentials when constructing the client, the
    // client library will look for credentials in the environment.
    var storage = StorageClient.Create();
    // Make an authenticated API request.
    var buckets = storage.ListBuckets(projectId);
    foreach (var bucket in buckets)
    {
        Console.WriteLine(bucket.Name);
    }
    return null;
}

Go

// For API packages whose import path is starting with "cloud.google.com/go",
// such as cloud.google.com/go/storage in this case, if there are no credentials
// provided, the client library will look for credentials in the environment.
storageClient, err := storage.NewClient(ctx)
if err != nil {
	log.Fatal(err)
}

it := storageClient.Buckets(ctx, "project-id")
for {
	bucketAttrs, err := it.Next()
	if err == iterator.Done {
		break
	}
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(bucketAttrs.Name)
}

// For packages whose import path is starting with "google.golang.org/api",
// such as google.golang.org/api/cloudkms/v1, use the
// golang.org/x/oauth2/google package as shown below.
oauthClient, err := google.DefaultClient(ctx, cloudkms.CloudPlatformScope)
if err != nil {
	log.Fatal(err)
}

kmsService, err := cloudkms.New(oauthClient)
if err != nil {
	log.Fatal(err)
}

Node.js

// Imports the Google Cloud client library.
const Storage = require('@google-cloud/storage');

// Instantiates a client. If you don't specify credentials when constructing
// the client, the client library will look for credentials in the
// environment.
const storage = Storage();

// Makes an authenticated API request.
storage
  .getBuckets()
  .then((results) => {
    const buckets = results[0];

    console.log('Buckets:');
    buckets.forEach((bucket) => {
      console.log(bucket.name);
    });
  })
  .catch((err) => {
    console.error('ERROR:', err);
  });

PHP

namespace Google\Cloud\Samples\Auth;

// Imports the Google Cloud Storage client library.
use Google\Cloud\Storage\StorageClient;

function auth_cloud_implicit($projectId)
{
    $config = [
        'projectId' => $projectId,
    ];

    # If you don't specify credentials when constructing the client, the
    # client library will look for credentials in the environment.
    $storage = new StorageClient($config);

    # Make an authenticated API request (listing storage buckets)
    foreach ($storage->buckets() as $bucket) {
        printf('Bucket: %s' . PHP_EOL, $bucket->name());
    }
}

Python

def implicit():
    from google.cloud import storage

    # If you don't specify credentials when constructing the client, the
    # client library will look for credentials in the environment.
    storage_client = storage.Client()

    # Make an authenticated API request
    buckets = list(storage_client.list_buckets())
    print(buckets)

Ruby

# project_id = "Your Google Cloud project ID"

require "google/cloud/storage"

# If you don't specify credentials when constructing the client, the client
# library will look for credentials in the environment.
storage = Google::Cloud::Storage.new project: project_id

# Make an authenticated API request
storage.buckets.each do |bucket|
  puts bucket.name
end

Como receber e fornecer credenciais da conta de serviço manualmente

Se você desenvolve o código localmente, implanta seu aplicativo no local ou em outra nuvem pública, é possível criar e receber manualmente as credenciais da conta de serviço.

Para mais informações sobre como criar uma conta de serviço, consulte Primeiros passos na autenticação. O guia vinculado ajuda você a criar uma conta de serviço com permissões de proprietário. Para um aplicativo de produção, restrinja o acesso às permissões, conforme descrito na seção abaixo, Como restringir o acesso.

Depois que você cria a conta de serviço e configura a variável de ambiente, o ADC consegue determinar suas credenciais implicitamente, conforme descrito na seção acima, Como fornecer credenciais para seu aplicativo. Recomendamos essa abordagem porque requer menos códigos.

Outra opção seria apontar explicitamente para seu arquivo da conta de serviço no código, conforme mostrado no exemplo de código a seguir.

C#

public object AuthExplicit(string projectId, string jsonPath)
{
    // Explicitly use service account credentials by specifying the private key
    // file.
    GoogleCredential credential = null;
    using (var jsonStream = new FileStream(jsonPath, FileMode.Open,
        FileAccess.Read, FileShare.Read))
    {
        credential = GoogleCredential.FromStream(jsonStream);
    }
    var storage = StorageClient.Create(credential);
    // Make an authenticated API request.
    var buckets = storage.ListBuckets(projectId);
    foreach (var bucket in buckets)
    {
        Console.WriteLine(bucket.Name);
    }
    return null;
}

Node.js

// Imports the Google Cloud client library.
const Storage = require('@google-cloud/storage');

// Instantiates a client. Explicitly use service account credentials by
// specifying the private key file. All clients in google-cloud-node have this
// helper, see https://googlecloudplatform.github.io/google-cloud-node/#/docs/google-cloud/latest/guides/authentication
const storage = Storage({
  keyFilename: '/path/to/keyfile.json'
});

// Makes an authenticated API request.
storage
  .getBuckets()
  .then((results) => {
    const buckets = results[0];

    console.log('Buckets:');
    buckets.forEach((bucket) => {
      console.log(bucket.name);
    });
  })
  .catch((err) => {
    console.error('ERROR:', err);
  });

PHP

namespace Google\Cloud\Samples\Auth;

// Imports the Google Cloud Storage client library.
use Google\Cloud\Storage\StorageClient;

function auth_cloud_explicit($projectId, $serviceAccountPath)
{
    # Explicitly use service account credentials by specifying the private key
    # file.
    $config = [
        'keyFilePath' => $serviceAccountPath,
        'projectId' => $projectId,
    ];
    $storage = new StorageClient($config);

    # Make an authenticated API request (listing storage buckets)
    foreach ($storage->buckets() as $bucket) {
        printf('Bucket: %s' . PHP_EOL, $bucket->name());
    }
}

Python

def explicit():
    from google.cloud import storage

    # Explicitly use service account credentials by specifying the private key
    # file.
    storage_client = storage.Client.from_service_account_json(
        'service_account.json')

    # Make an authenticated API request
    buckets = list(storage_client.list_buckets())
    print(buckets)

Ruby

# project_id = "Your Google Cloud project ID"
# key_file   = "path/to/service-account.json"
require "google/cloud/storage"

# Explicitly use service account credentials by specifying the private key
# file.
storage = Google::Cloud::Storage.new project: project_id, keyfile: key_file

# Make an authenticated API request
storage.buckets.each do |bucket|
  puts bucket.name
end

Como receber credenciais no Compute Engine, Kubernetes Engine, ambiente flexível do App Engine e Cloud Functions

Quando o aplicativo é executado no Compute Engine, Kubernetes Engine, ambiente flexível do App Engine ou Cloud Functions, você não precisa de uma conta de serviço. O Compute Engine inclui uma conta de serviço padrão criada automaticamente. Além disso, é possível atribuir uma conta de serviço diferente, por instância, se necessário. Quando você cria uma nova instância, ela é ativada automaticamente para ser executada como a conta padrão e com um conjunto de permissões de autorização padrão. Para mais informações, consulte a conta do serviço padrão do Compute Engine.

Depois que você configura uma conta de serviço, o ADC consegue encontrar suas credenciais implicitamente sem que o código precise ser alterado, conforme descrito na seção acima. Para usar credenciais específicas do Compute Engine, faça-o explicitamente, conforme o código abaixo.

C#

public object AuthExplicitComputeEngine(string projectId)
{
    // Explicitly use service account credentials by specifying the
    // private key file.
    GoogleCredential credential =
        GoogleCredential.FromComputeCredential();
    var storage = StorageClient.Create(credential);
    // Make an authenticated API request.
    var buckets = storage.ListBuckets(projectId);
    foreach (var bucket in buckets)
    {
        Console.WriteLine(bucket.Name);
    }
    return null;
}

PHP

namespace Google\Cloud\Samples\Auth;

// Imports GCECredentials and the Google Cloud Storage client library.
use Google\Auth\Credentials\GCECredentials;
use Google\Cloud\Storage\StorageClient;

function auth_cloud_explicit_compute_engine($projectId)
{
    $gceCredentials = new GCECredentials();
    $config = [
        'projectId' => $projectId,
        'credentialsFetcher' => $gceCredentials,
    ];
    $storage = new StorageClient($config);

    # Make an authenticated API request (listing storage buckets)
    foreach ($storage->buckets() as $bucket) {
        printf('Bucket: %s' . PHP_EOL, $bucket->name());
    }
}

Python

def explicit_compute_engine(project):
    from google.auth import compute_engine
    from google.cloud import storage

    # Explicitly use Compute Engine credentials. These credentials are
    # available on Compute Engine, App Engine Flexible, and Container Engine.
    credentials = compute_engine.Credentials()

    # Create the client using the credentials and specifying a project ID.
    storage_client = storage.Client(credentials=credentials, project=project)

    # Make an authenticated API request
    buckets = list(storage_client.list_buckets())
    print(buckets)

Ruby

require "googleauth"
require "google/cloud/env"
require "google/cloud/storage"

# Explicitly use Compute Engine credentials and a project ID to create a new
# Cloud Storage client. These credentials are available on Compute Engine,
# App Engine Flexible, and Container Engine.
storage = Google::Cloud::Storage.new project: Google::Cloud.env.project_id,
                                     keyfile: Google::Auth::GCECredentials.new

# Make an authenticated API request
storage.buckets.each do |bucket|
  puts bucket.name
end

Como receber credenciais no ambiente padrão do App Engine

Para que seu aplicativo seja executado no ambiente padrão do App Engine, use a App Engine App Identity API para receber as credenciais.

Depois que você configura uma conta de serviço, o ADC consegue encontrar suas credenciais implicitamente sem que o código precise ser alterado, conforme descrito na seção acima. Para usar credenciais específicas do App Engine, faça-o explicitamente, conforme o código abaixo.

PHP

namespace Google\Cloud\Samples\Auth;

// Imports AppIdentityCredentials and the Google Cloud Storage client library.
use Google\Auth\Credentials\AppIdentityCredentials;
use Google\Cloud\Storage\StorageClient;

function auth_cloud_explicit_app_engine($projectId)
{
    # Learn more about scopes at https://cloud.google.com/storage/docs/authentication#oauth-scopes
    $scope = 'https://www.googleapis.com/auth/devstorage.read_only';
    $gaeCredentials = new AppIdentityCredentials($scope);
    $config = [
        'projectId' => $projectId,
        'credentialsFetcher' => $gaeCredentials,
    ];
    $storage = new StorageClient($config);

    # Make an authenticated API request (listing storage buckets)
    foreach ($storage->buckets() as $bucket) {
        printf('Bucket: %s' . PHP_EOL, $bucket->name());
    }
}

Python

def explicit_app_engine(project):
    from google.auth import app_engine
    import googleapiclient.discovery

    # Explicitly use App Engine credentials. These credentials are
    # only available when running on App Engine Standard.
    credentials = app_engine.Credentials()

    # Explicitly pass the credentials to the client library.
    storage_client = googleapiclient.discovery.build(
        'storage', 'v1', credentials=credentials)

    # Make an authenticated API request
    buckets = storage_client.buckets().list(project=project).execute()
    print(buckets)

Como restringir o acesso

Basta conceder ao aplicativo as permissões de autorização necessárias para interagir com as APIs, os recursos ou as funcionalidades aplicáveis do GCP. O GCP utiliza o Cloud Identity and Access Management (Cloud IAM) para o controle de acesso. Ao criar uma conta de serviço, escolha um papel do Cloud IAM para limitar o acesso. Nas instruções dos Primeiros passos na autenticação, você é orientado a escolher o papel Owner quando uma conta de serviço é criada. É possível alterar esse valor a qualquer momento. Para mais informações, consulte Como conceder papéis às contas de serviço.

Práticas recomendadas para o gerenciamento de credenciais

As credenciais fornecem acesso a dados confidenciais. As práticas a seguir ajudam você a proteger o acesso a esses recursos.

  • Não incorpore chaves secretas relacionadas à autenticação no código-fonte, como chaves de API, tokens OAuth e credenciais da conta de serviço. Use uma variável de ambiente que aponte para as credenciais fora do código-fonte do aplicativo, como o Cloud Key Management Service.

  • Use credenciais diferentes em contextos distintos como ambientes de teste e de produção.

  • Transfira credenciais apenas por meio de HTTPS para evitar a interceptação de suas credenciais por terceiros. Jamais transfira em texto simples ou como parte do URL.

  • Nunca incorpore credenciais de longa duração no aplicativo do lado do cliente. Por exemplo, não incorpore credenciais da conta de serviço em um aplicativo para dispositivos móveis. Os aplicativos do lado do cliente podem ser examinados e as credenciais facilmente encontradas e usadas por terceiros.

  • Revogue um token quando ele não for mais necessário.

Solução de problemas de erros na API

Saiba mais sobre como resolver problemas de solicitações de API com falha em Erros nas APIs do Cloud.

Próximas etapas

Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…