Inicie sessão através da autenticação da base de dados de IAM

Esta página descreve como os utilizadores e as contas de serviço podem iniciar sessão em bases de dados do Cloud SQL através da autenticação de base de dados do Cloud SQL IAM. Para mais informações, consulte o artigo Autenticação da IAM.

Antes de começar

  • Configure a instância para usar a autenticação da base de dados da IAM. Para mais informações, consulte o artigo Configure novas instâncias para a autenticação da base de dados da IAM.
  • Adicione um utilizador, uma conta de serviço ou um grupo do IAM à base de dados. Para mais informações, consulte Adicione um utilizador ou uma conta de serviço do IAM à base de dados e Adicione um grupo à base de dados.
  • Adicione a função de IAM roles/cloudsql.instanceUser ao seu utilizador de IAM, conta de serviço ou grupo. É uma função predefinida que contém a autorização de IAM do Cloud SQL cloudsql.instances.login necessária. Precisa desta autorização para iniciar sessão numa instância da base de dados com a autenticação da base de dados do IAM. Para mais informações, consulte o artigo Funções e autorizações.
  • Se estiver a usar o proxy de autorização do Cloud SQL, adicione a função de roles/cloudsql.client IAM ao seu utilizador, conta de serviço ou grupo do IAM. É uma função predefinida que contém a autorização de IAM cloudsql.instances.connect do Cloud SQL necessária. Precisa desta autorização para iniciar sessão numa instância da base de dados com o proxy Auth do Cloud SQL. Para mais informações, consulte o artigo Funções e autorizações.
  • Quando um utilizador do IAM é adicionado a uma base de dados, o novo utilizador da base de dados não tem privilégios em nenhuma base de dados por predefinição. Tem de usar o comando GRANT para conceder ao utilizador da base de dados do IAM as autorizações necessárias. Para mais informações, consulte os artigos Conceda privilégios de base de dados ao utilizador do IAM e Conceda privilégios de base de dados a um grupo.

  • Se estiver a usar a autenticação de grupo do IAM, o utilizador do IAM ou a conta de serviço tem de ser membro de um grupo ao qual foi concedida uma função ou autorizações do IAM para iniciar sessão na instância do Cloud SQL. O Cloud SQL cria uma conta depois de o utilizador ou a conta de serviço iniciar sessão na instância pela primeira vez.

Inicie sessão com a autenticação automática da base de dados do IAM

Pode configurar um conetor do Cloud SQL para processar automaticamente a autenticação na instância do Cloud SQL em nome de um utilizador ou de uma aplicação. Os conetores incluem o proxy Auth do Cloud SQL, o conetor Go, o conetor Java e o conetor Python, que suportam a autenticação automática da base de dados do IAM. Quando usar um conetor do Cloud SQL com a autenticação de base de dados do IAM automática, a conta do IAM que usa para iniciar o conetor tem de ser a mesma conta que autentica a base de dados.

Para iniciar sessão através da autenticação automática da base de dados do IAM:

Proxy Auth do Cloud SQL

  1. Autentique-se em Google Cloud.

    Utilizador

    Autentique-se no Google Cloud com as Credenciais padrão da aplicação (ADC).

    Use o comando gcloud auth application-default login. Para mais informações, consulte o artigo Configure as Credenciais padrão da aplicação.

    Conta de serviço

    Para fazer a autenticação no Google Cloud com o ADC e uma conta de serviço, pode usar a simulação da conta de serviço ou configurar uma chave da conta de serviço. Se quiser autenticar com a representação da conta de serviço, substitua SERVICE_ACCOUNT_EMAIL_ADDRESS e execute o seguinte comando:

    gcloud auth application-default login --impersonate-service-account SERVICE_ACCOUNT_EMAIL_ADDRESS

    Para mais informações, consulte o artigo Configure as Credenciais padrão da aplicação.

  2. Inicie o proxy Auth do Cloud SQL com a flag --auto-iam-authn Substitua INSTANCE_CONNECTION_NAME pela string de ligação usada para identificar a instância do Cloud SQL. Se estiver a usar uma porta diferente da porta predefinida do MySQL, especifique o número da porta. Para mais informações sobre como encontrar e criar esta string, consulte Opções para autenticar o proxy Auth do Cloud SQL.

    ./cloud-sql-proxy --auto-iam-authn INSTANCE_CONNECTION_NAME

    Para mais informações sobre como iniciar o proxy, consulte o artigo Inicie o proxy Auth do Cloud SQL.

  3. Quando estiver pronto para estabelecer ligação à instância através do proxy Auth do Cloud SQL, inicie sessão com o cliente mysql. Substitua o seguinte:

    • HOSTNAME: endereço IP usado pelo proxy Auth do Cloud SQL. Por predefinição, o proxy Auth do Cloud SQL usa o endereço de localhost de 127.0.0.1, mas pode atribuir um endereço IP diferente quando inicia o proxy Auth do Cloud SQL.
    • USERNAME: Para uma conta de utilizador do IAM, este é o endereço de email do utilizador, sem o símbolo @ nem o nome do domínio. Por exemplo, para test-user@example.com, introduza test-user. Para uma conta de serviço, trata-se do endereço de email da conta de serviço sem o sufixo @project-id.iam.gserviceaccount.com.
    • PORT_NUMBER: opcional. Se especificou uma porta diferente na string de ligação da instância, especifique esse número da porta.

    Execute o seguinte comando:

    mysql --host=HOSTNAME \
    --user=USERNAME \
    --port=PORT_NUMBER

    Para mais informações sobre como estabelecer ligação ao proxy Auth do Cloud SQL, consulte o artigo Estabeleça ligação com o cliente mysql.

Ir

import (
	"context"
	"database/sql"
	"fmt"
	"log"
	"net"
	"os"

	"cloud.google.com/go/cloudsqlconn"
	"github.com/go-sql-driver/mysql"
)

func connectWithConnectorIAMAuthN() (*sql.DB, error) {
	mustGetenv := func(k string) string {
		v := os.Getenv(k)
		if v == "" {
			log.Fatalf("Warning: %s environment variable not set.", k)
		}
		return v
	}
	// Note: Saving credentials in environment variables is convenient, but not
	// secure - consider a more secure solution such as
	// Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
	// keep secrets safe.
	var (
		dbUser                 = mustGetenv("DB_IAM_USER")              // e.g. 'service-account-name'
		dbName                 = mustGetenv("DB_NAME")                  // e.g. 'my-database'
		instanceConnectionName = mustGetenv("INSTANCE_CONNECTION_NAME") // e.g. 'project:region:instance'
		usePrivate             = os.Getenv("PRIVATE_IP")
	)

	// WithLazyRefresh() Option is used to perform refresh
	// when needed, rather than on a scheduled interval.
	// This is recommended for serverless environments to
	// avoid background refreshes from throttling CPU.
	d, err := cloudsqlconn.NewDialer(
		context.Background(),
		cloudsqlconn.WithIAMAuthN(),
		cloudsqlconn.WithLazyRefresh(),
	)
	if err != nil {
		return nil, fmt.Errorf("cloudsqlconn.NewDialer: %w", err)
	}
	var opts []cloudsqlconn.DialOption
	if usePrivate != "" {
		opts = append(opts, cloudsqlconn.WithPrivateIP())
	}
	mysql.RegisterDialContext("cloudsqlconn",
		func(ctx context.Context, addr string) (net.Conn, error) {
			return d.Dial(ctx, instanceConnectionName, opts...)
		})

	dbURI := fmt.Sprintf("%s:empty@cloudsqlconn(localhost:3306)/%s?parseTime=true",
		dbUser, dbName)

	dbPool, err := sql.Open("mysql", dbURI)
	if err != nil {
		return nil, fmt.Errorf("sql.Open: %w", err)
	}
	return dbPool, nil
}

Java JDBC

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import javax.sql.DataSource;

public class ConnectorIamAuthnConnectionPoolFactory extends ConnectionPoolFactory {

  // Note: Saving credentials in environment variables is convenient, but not
  // secure - consider a more secure solution such as
  // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
  // keep secrets safe.
  private static final String INSTANCE_CONNECTION_NAME =
      System.getenv("INSTANCE_CONNECTION_NAME");
  private static final String INSTANCE_UNIX_SOCKET = System.getenv("INSTANCE_UNIX_SOCKET");
  private static final String DB_IAM_USER = System.getenv("DB_IAM_USER");
  private static final String DB_NAME = System.getenv("DB_NAME");


  public static DataSource createConnectionPool() {
    // The configuration object specifies behaviors for the connection pool.
    HikariConfig config = new HikariConfig();

    // The following URL is equivalent to setting the config options below:
    // jdbc:mysql:///<DB_NAME>?cloudSqlInstance=<INSTANCE_CONNECTION_NAME>&
    // socketFactory=com.google.cloud.sql.mysql.SocketFactory&user=<DB_USER>&password=<DB_PASS>
    // See the link below for more info on building a JDBC URL for the Cloud SQL JDBC Socket Factory
    // https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory#creating-the-jdbc-url

    // Configure which instance and what database user to connect with.
    config.setJdbcUrl(String.format("jdbc:mysql:///%s", DB_NAME));

    config.addDataSourceProperty("socketFactory", "com.google.cloud.sql.mysql.SocketFactory");
    config.addDataSourceProperty("cloudSqlInstance", INSTANCE_CONNECTION_NAME);

    // If connecting using automatic database authentication, follow the instructions for
    // connecting using the connector, but set the DB_IAM_USER value to an IAM user or
    // service account that has been given access to the database.
    // See https://cloud.google.com/sql/docs/postgres/iam-logins for more details.
    config.addDataSourceProperty("enableIamAuth", "true");
    config.addDataSourceProperty("user", DB_IAM_USER);
    // Explicitly set sslmode to disable to prevent driver from hanging.
    // The Java Connector will handle SSL so it is unneccesary to enable it at the driver level.
    config.addDataSourceProperty("sslmode", "disable");

    // cloudSqlRefreshStrategy set to "lazy" is used to perform a
    // refresh when needed, rather than on a scheduled interval.
    // This is recommended for serverless environments to
    // avoid background refreshes from throttling CPU.
    config.addDataSourceProperty("cloudSqlRefreshStrategy", "lazy");


    // ... Specify additional connection properties here.
    // ...

    // Initialize the connection pool using the configuration object.
    return new HikariDataSource(config);
  }
}

Java R2DBC

// Set up ConnectionFactoryOptions
ConnectionFactoryOptions options =
    ConnectionFactoryOptions.builder()
        .option(DRIVER, "gcp")
        .option(PROTOCOL, "mysql")
        .option(USER, DB_USER)
        .option(DATABASE, DB_NAME)
        .option(HOST, CONNECTION_NAME)
        .option(IP_TYPES, IP_TYPE)
        .option(ENABLE_IAM_AUTH, true)
        .build();

// Initialize connection pool
ConnectionFactory connectionFactory = ConnectionFactories.get(options);
ConnectionPoolConfiguration configuration =
    ConnectionPoolConfiguration.builder(connectionFactory).build();

this.connectionPool = new ConnectionPool(configuration);

Python

import os

from google.cloud.sql.connector import Connector, IPTypes
import pymysql

import sqlalchemy


def connect_with_connector_auto_iam_authn() -> sqlalchemy.engine.base.Engine:
    """
    Initializes a connection pool for a Cloud SQL instance of MySQL.

    Uses the Cloud SQL Python Connector with Automatic IAM Database Authentication.
    """
    # Note: Saving credentials in environment variables is convenient, but not
    # secure - consider a more secure solution such as
    # Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
    # keep secrets safe.
    instance_connection_name = os.environ[
        "INSTANCE_CONNECTION_NAME"
    ]  # e.g. 'project:region:instance'
    db_iam_user = os.environ["DB_IAM_USER"]  # e.g. 'service-account-name'
    db_name = os.environ["DB_NAME"]  # e.g. 'my-database'

    ip_type = IPTypes.PRIVATE if os.environ.get("PRIVATE_IP") else IPTypes.PUBLIC

    # initialize Cloud SQL Python Connector object
    connector = Connector(refresh_strategy="LAZY")

    def getconn() -> pymysql.connections.Connection:
        conn: pymysql.connections.Connection = connector.connect(
            instance_connection_name,
            "pymysql",
            user=db_iam_user,
            db=db_name,
            enable_iam_auth=True,
            ip_type=ip_type,
        )
        return conn

    # The Cloud SQL Python Connector can be used with SQLAlchemy
    # using the 'creator' argument to 'create_engine'
    pool = sqlalchemy.create_engine(
        "mysql+pymysql://",
        creator=getconn,
        # ...
    )
    return pool

Inicie sessão com a autenticação manual da base de dados IAM

Um utilizador ou uma aplicação pode autenticar-se na base de dados através do IAM pedindo manualmente um token de acesso a Google Cloud e apresentando-o à base de dados. Com a CLI gcloud, pode pedir explicitamente um token do OAuth 2.0 com o âmbito da API Cloud SQL Admin que é usado para iniciar sessão na base de dados. Quando inicia sessão como um utilizador da base de dados com a autenticação manual da base de dados do IAM, usa o seu endereço de email como nome de utilizador e o token de acesso como palavra-passe. Pode usar este método com uma ligação direta à base de dados ou com um conetor do Cloud SQL.

Neste procedimento, autentica-se no Google Cloud, pede um token de acesso e, em seguida, liga-se à base de dados transmitindo o token como a palavra-passe do utilizador da base de dados do IAM. Use estes passos para estabelecer ligação sem o proxy Auth do Cloud SQL.

Para estes passos, tem de:

Para iniciar sessão através da autenticação manual da base de dados de IAM:

gcloud

  1. Autentique-se em Google Cloud.

    Utilizador

    Faça a autenticação no IAM através de gcloud auth login. Para mais informações, consulte o artigo Autorize com uma conta de utilizador.

    Conta de serviço

    Faça a autenticação no IAM através de gcloud auth activate-service-account. Para mais informações, consulte o artigo Autorize com uma conta de serviço.

  2. Peça o token de acesso e inicie sessão com um cliente.

    Substitua o seguinte:

    • HOSTNAME: O endereço IP da instância, o endereço IP público ou o endereço IP privado.
    • USERNAME: para uma conta de utilizador do IAM, este é o endereço de email do utilizador, sem o símbolo @ nem o nome do domínio. Por exemplo, para test-user@example.com, introduza test-user. Para uma conta de serviço, trata-se do endereço de email da conta de serviço sem o sufixo @project-id.iam.gserviceaccount.com.

     MYSQL_PWD=`gcloud sql generate-login-token` \
     mysql --enable-cleartext-plugin \
     --ssl-mode=REQUIRED \
     --host=HOSTNAME \
     --user=USERNAME
     

    Se ssl_mode na sua instância do Cloud SQL estiver configurado para TRUSTED_CLIENT_CERTIFICATE_REQUIRED, inclua um certificado de cliente e uma chave de cliente quando iniciar sessão. Além disso, para permitir que o cliente valide a identidade do servidor para fins de autenticação mútua, especifique o certificado do servidor server-ca.pem. Por exemplo:

     MYSQL_PWD=`gcloud sql generate-login-token` \
     mysql --enable-cleartext-plugin \
     --ssl-mode=VERIFY_CA \
     --ssl-ca=server-ca.pem \
     --ssl-cert=client-cert.pem \
     --ssl-key=client-key.pem \
     --host=HOSTNAME \
     --user=USERNAME
     

    Para ver informações sobre como criar um certificado de cliente e uma chave, consulte o artigo Certificados de cliente.

O que se segue?