Eseguire l'autenticazione e connettersi a un database

Pertinente solo per la versione Enterprise di Cloud Firestore.

Requisiti di connessione

Per i client Cloud Firestore con compatibilità MongoDB sono necessari i seguenti elementi:

  • I conducenti devono connettersi in modalità load balanced. In questo modo, i driver non tentano di comprendere la topologia esatta del server a cui si connettono.
  • I driver devono connettersi con SSL abilitato.
  • I driver devono disattivare le scritture ripetibili. Cloud Firestore con compatibilità MongoDB non supporta le scritture ripetibili. Non è necessario disattivare le letture ripetibili perché sono supportate.

Recuperare la stringa di connessione

La stringa di connessione al database dipende dall'UID del database, dalla posizione del database e dal meccanismo di autenticazione. Le istruzioni seguenti descrivono come viene formata la stringa di connessione.

La stringa di connessione esatta dipende dal meccanismo di autenticazione, ma la stringa di connessione di base utilizza il seguente formato:

mongodb://UID.LOCATION.firestore.goog:443/DATABASE_ID?loadBalanced=true&tls=true&retryWrites=false

Puoi ottenere la stringa di connessione di base in uno dei seguenti modi:

Firebase console
  1. Nella console Firebase, vai alla pagina Database Firestore.

    Vai al database Firestore

  2. Fai clic sul database da autenticare.
  3. Nel riquadro Explorer, fai clic su Visualizza altro.
  4. Seleziona Connettiti utilizzando gli strumenti MongoDB.
  5. Copia la stringa di connessione.
gcloud

Utilizza gcloud firestore database describe per recuperare l'UID e le informazioni sulla posizione:

gcloud firestore databases describe \
--database=DATABASE_ID \
--format='yaml(locationId, uid)'

Sostituisci DATABASE_ID con l'ID database.

L'output include la posizione e l'UID del database. Utilizza queste informazioni per creare la stringa di connessione di base.

Utilizza la stringa di connessione di base e uno dei seguenti metodi per autenticarti e connetterti al tuo database:

Connettersi con nome utente e password (SCRAM)

Segui questi passaggi per creare una credenziale utente per il tuo database e connetterti al database.

Prima di iniziare

Per ottenere le autorizzazioni necessarie per creare un utente, chiedi all'amministratore di concederti il ruolo IAM userCredsAdmin (roles/datastore.userCredsAdmin) sul database. Per saperne di più sulla concessione dei ruoli, consulta Gestisci l'accesso a progetti, cartelle e organizzazioni.

Potresti anche riuscire a ottenere le autorizzazioni richieste tramite i ruoli personalizzati o altri ruoli predefiniti.

Crea un utente e connettiti a un database

Per creare un utente per il tuo database Cloud Firestore con compatibilità MongoDB, utilizza uno dei seguenti metodi:

Console Google Cloud
  1. Nella console Google Cloud, vai alla pagina Database.

    Vai a Database

  2. Seleziona un database dall'elenco.
  3. Nel menu di navigazione, fai clic su Autenticazione.
  4. Fai clic su Aggiungi utente.
  5. Inserisci un nome utente.
  6. Seleziona un ruolo per il nuovo utente.
  7. Fai clic su Aggiungi.

    La password del nuovo utente verrà visualizzata nella finestra di dialogo di conferma.

gcloud CLI
  1. Per l'autenticazione con SCRAM, devi prima creare una credenziale utente. Utilizza il comando gcloud firestore user-creds:
    gcloud firestore user-creds create USERNAME --database=DATABASE_ID
    Sostituisci quanto segue:
    • USERNAME: il nome utente da creare.
    • DATABASE_ID: l'ID del database.

    L'output di questo comando include la password dell'utente.

    L'output è simile al seguente:

    name: projects/PROJECT_NAME/databases/DATABASE_ID/userCreds/USERNAME
    resourceIdentity:
      principal: principal://firestore.googleapis.com/projects/PROJECT_NUMBER/name/databases/DATABASE_ID/userCreds/USERNAME
    securePassword: PASSWORD
  2. Per impostazione predefinita, queste nuove credenziali utente non dispongono di alcuna autorizzazione. Per l'accesso in lettura e scrittura al database, aggiungi il ruolo roles/datastore.user per questo database specifico:

    gcloud projects add-iam-policy-binding PROJECT_NAME \
    --member='principal://firestore.googleapis.com/projects/PROJECT_NUMBER/name/databases/DATABASE_ID/userCreds/USERNAME' \
    --role=roles/datastore.user \
    --condition='expression=resource.name == "projects/PROJECT_NAME/databases/DATABASE_ID",title="CONDITION_TITLE"'
    Sostituisci quanto segue:
Java

Questa sezione fornisce un esempio di codice per creare le credenziali utente e configurare il criterio IAM utilizzando le librerie client di amministrazione Java. L'esempio utilizza la libreria Firestore Admin Client per creare un nome utente e una password e la libreria Google Cloud Resource Manager per configurare IAM.

Per le build Maven, puoi utilizzare le seguenti coordinate:

com.google.cloud:google-cloud-firestore-admin:3.33.1
com.google.cloud:google-cloud-resourcemanager:1.76.0

Esegui il provisioning delle credenziali utente e di una policy IAM:

import com.google.cloud.firestore.v1.FirestoreAdminClient;
import com.google.cloud.resourcemanager.v3.ProjectName;
import com.google.cloud.resourcemanager.v3.ProjectsClient;
import com.google.firestore.admin.v1.CreateUserCredsRequest;
import com.google.firestore.admin.v1.GetUserCredsRequest;
import com.google.firestore.admin.v1.UserCreds;
import com.google.iam.v1.Binding;
import com.google.iam.v1.GetIamPolicyRequest;
import com.google.iam.v1.GetPolicyOptions;
import com.google.iam.v1.Policy;
import com.google.iam.v1.SetIamPolicyRequest;
import com.google.protobuf.FieldMask;
import com.google.type.Expr;

public class FirestoreUserCredsExample {
  /**
   * Provision user credentials and configure an IAM policy to allow SCRAM authentication into the
   * specified Firestore with Mongo Compatibility database.
   */
  private static void provisionFirestoreUserCredsAndIAM(
      String projectId, String databaseId, String userName) throws Exception {
    UserCreds userCreds = createUserCreds(projectId, databaseId, userName);

    // Note the password returned in the UserCreds proto - it cannot be retrieved again
    // after the initial call to the createUserCreds API.
    System.out.printf(
        "Created credentials for username: %s:\nIAM principal: %s\nPassword: [%s]\n",
        userName, userCreds.getResourceIdentity().getPrincipal(), userCreds.getSecurePassword());

    // Provision an IAM binding for the principal associated with these user credentials.
    updateIamPolicyForUserCreds(projectId, databaseId, userName, userCreds);

    // Emit the password again.
    System.out.printf(
        "Successfully configured IAM policy for database: %s, username: %s\n",
        databaseId, userName);
    System.out.printf("Please make a note of the password: [%s]\n", userCreds.getSecurePassword());
  }

  /** Provision new user credentials using the FirestoreAdminClient. */
  private static UserCreds createUserCreds(String projectId, String databaseId, String userName)
      throws Exception {
    FirestoreAdminClient firestoreAdminClient = FirestoreAdminClient.create();
    return firestoreAdminClient.createUserCreds(
        CreateUserCredsRequest.newBuilder()
            .setParent(String.format("projects/%s/databases/%s", projectId, databaseId))
            .setUserCredsId(userName)
            .build());
  }

  /** Update the IAM policy using the Resource Manager ProjectsClient. */
  private static void updateIamPolicyForUserCreds(
      String projectId, String databaseId, String userName, UserCreds userCreds) throws Exception {
    try (ProjectsClient projectsClient = ProjectsClient.create()) {
      ProjectName projectName = ProjectName.of(projectId);

      // Get the current IAM policy.
      Policy currentPolicy =
          projectsClient.getIamPolicy(
              GetIamPolicyRequest.newBuilder()
                  .setResource(projectName.toString())
                  .setOptions(GetPolicyOptions.newBuilder().setRequestedPolicyVersion(3).build())
                  .build());

      String role = "roles/datastore.user";
      String title = String.format("Conditional IAM binding for %s", userName);
      String expression =
          String.format("resource.name == \"projects/%s/databases/%s\"", projectId, databaseId);

      // Construct an updated IAM policy with an additional binding for the user credentials.
      Policy.Builder policyBuilder = currentPolicy.toBuilder();
      Binding newBinding =
          Binding.newBuilder()
              .setRole(role)
              .setCondition(Expr.newBuilder().setTitle(title).setExpression(expression).build())
              .addMembers(userCreds.getResourceIdentity().getPrincipal())
              .build();
      policyBuilder.addBindings(newBinding);

      // Update the policy
      SetIamPolicyRequest request =
          SetIamPolicyRequest.newBuilder()
              .setResource(projectName.toString())
              .setPolicy(policyBuilder.build())
              .setUpdateMask(FieldMask.newBuilder().addPaths("bindings").addPaths("etag").build())
              .build();
      System.out.println(request);

      Policy updatedPolicy = projectsClient.setIamPolicy(request);
      System.out.println("Policy updated successfully: " + updatedPolicy);
    }
  }
}
Python

Questa sezione fornisce un esempio di codice per la creazione delle credenziali utente e la configurazione del criterio IAM utilizzando le librerie client di amministrazione Python. L'esempio utilizza la libreria client dell'API Google Cloud Firestore per creare un nome utente e una password, nonché la libreria client dell'API Google Cloud IAM e la libreria client dell'API Google Cloud Resource Manager per configurare IAM.

Le librerie Python richieste possono essere installate con lo strumento pip:

pip install google-cloud-iam
pip install google-cloud-firestore
pip install google-cloud-resource-manager

Esegui il provisioning delle credenziali utente e di una policy IAM:

from google.cloud import resourcemanager_v3
from google.cloud.firestore_admin_v1 import FirestoreAdminClient
from google.cloud.firestore_admin_v1 import types
from google.iam.v1 import iam_policy_pb2
from google.iam.v1 import policy_pb2
from google.type import expr_pb2


def create_user_creds(project_id: str, database_id: str, user_name: str):
  """Provision new user credentials using the FirestoreAdminClient."""
  client = FirestoreAdminClient()
  request = types.CreateUserCredsRequest(
      parent=f'projects/{project_id}/databases/{database_id}',
      user_creds_id=user_name,
  )
  response = client.create_user_creds(request)
  return response


def update_iam_policy_for_user_creds(
    project_id: str, database_id: str, user_name: str, user_creds
):
  """Update the IAM policy using the Resource Manager ProjectsClient."""
  client = resourcemanager_v3.ProjectsClient()
  request = iam_policy_pb2.GetIamPolicyRequest()
  request.resource = f'projects/{project_id}'
  request.options.requested_policy_version = 3

  # Get the current IAM policy
  current_policy = client.get_iam_policy(request)

  # Construct an updated IAM policy with an additional binding
  # for the user credentials.
  updated_policy = policy_pb2.Policy()
  binding = policy_pb2.Binding()
  iam_condition = expr_pb2.Expr()

  iam_condition.title = f'Conditional IAM binding for {user_name}'
  iam_condition.expression = (
      f'resource.name == "projects/{project_id}/databases/{database_id}"'
  )

  binding.role = 'roles/datastore.user'
  binding.condition.CopyFrom(iam_condition)
  binding.members.append(user_creds.resource_identity.principal)
  updated_policy.bindings.append(binding)

  # Update the policy
  updated_policy.MergeFrom(current_policy)
  set_policy_request = iam_policy_pb2.SetIamPolicyRequest()
  set_policy_request.resource = f'projects/{project_id}'
  set_policy_request.policy.CopyFrom(updated_policy)

  final_policy = client.set_iam_policy(set_policy_request)
  print(f'Policy updated successfully {final_policy}')


def provision_firestore_user_creds_and_iam(
    project_id: str, database_id: str, user_name: str
):
  """Provision user credentials and configure an IAM policy."""
  user_creds = create_user_creds(project_id, database_id, user_name)

  # Note the password returned in the UserCreds proto - it cannot be
  # retrieved again after the initial call to the create_user_creds API.
  print(f'Created credentials for username: {user_name}')
  print(f'IAM principal: {user_creds.resource_identity.principal}')
  print(f'Password: [{user_creds.secure_password}]')

  # Provision an IAM binding for the principal associated with
  # these user credentials.
  update_iam_policy_for_user_creds(
      project_id, database_id, user_name, user_creds
  )

  # Emit the password again
  print(
      f'Successfully configured IAM policy for database: {database_id},'
      f' username: {user_name}'
  )
  print(f'Please make a note of the password: [{user_creds.secure_password}]')

Utilizza la seguente stringa di connessione per connetterti al tuo database con SCRAM:

mongodb://USERNAME:PASSWORD@UID.LOCATION.firestore.goog:443/DATABASE_ID?loadBalanced=true&authMechanism=SCRAM-SHA-256&tls=true&retryWrites=false

Sostituisci quanto segue:

  • USERNAME: il nome utente.
  • PASSWORD: la password che hai generato per questo utente.
  • UID: l'UID del database.
  • LOCATION: la posizione del database.
  • DATABASE_ID: l'ID del database.

Connettersi alla libreria di autenticazione Google

Il seguente codice campione registra un gestore di callback OIDC che utilizza la Google Cloud libreria OAuth standard.

Questa libreria ti consente di utilizzare diversi tipi di autenticazione (credenziali predefinite dell'applicazione, federazione delle identità per la forza lavoro).

Per questo è necessario aggiungere la libreria di autenticazione come dipendenza:

// Maven
<dependency>
  <groupId>com.google.auth</groupId>
  <artifactId>google-auth-library-oauth2-http</artifactId>
  <version>1.19.0</version>
</dependency>

// Gradle
implementation 'com.google.auth:google-auth-library-oauth2-http:1.19.0'

Il seguente esempio di codice mostra come connettersi:

val db = MongoClients.create(
    clientSettings(
      "DATABASE_UID",
      "LOCATION"
    ).build()
  ).getDatabase("DATABASE_ID")


/**
 * Creates a connection to a Firestore with MongoDB Compatibility database.
 * @param databaseUid The uid of the database to connect to as a string. For example: f116f93a-519c-208a-9a72-3ef6c9a1f081
 * @param locationId The location of the database to connect to, for example: nam5, us-central1, us-east4 etc...
 * @param environment Determines whether to try and fetch an authentication credential from the
 * Compute Engine VM metadata service or whether to call gcloud.
 */
private static MongoClientSettings.Builder clientSettings(
  String databaseUid: String
  String locationId:String
): MongoClientSettings.Builder {
  MongoCredential credential =
    MongoCredential.createOidcCredential(null)
      .withMechanismProperty(
        MongoCredential.OIDC_CALLBACK_KEY,
        new MongoCredential.OidcCallback() {
          @Override
          MongoCredential.OidcCallbackResult onRequest(
MongoCredential.OidcCallbackContext context) {
     // Customize this credential builder for additional credential types.
     GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();
            return new MongoCredential.OidcCallbackResult(
         credentials.getAccessToken().getTokenValue(),
         Duration.between(Instant.now(),
credentials.getAccessToken().getExpirationTime().toInstant()));
          }
        },
      );
  return MongoClientSettings.builder()
    .hosts(listOf(ServerAddress(
        "$databaseUid.$locationId.firestore.goog", 443)))
    .credential(credential)
    .applyToClusterSettings(builder ->
         builder.mode(ClusterConnectionMode.LOAD_BALANCED))
    ).applyToSslSettings(ssl -> ssl.enabled(true)).retryWrites(false);
}

Sostituisci quanto segue:

  • DATABASE_UID: il nome del progetto.
  • LOCATION: la posizione del database.
  • DATABASE_ID l'ID database.

Connessione da un ambiente di calcolo Google Cloud

Questa sezione descrive la connessione a Cloud Firestore con compatibilità MongoDB da un ambiente di computing Google Cloud, ad esempio Compute Engine o un servizio o un job Cloud Run.

Connettiti da una VM Compute Engine

Puoi autenticarti e connetterti al tuo database utilizzando un service account Compute Engine. Per farlo, crea un criterio IAM per il progetto Google Cloud che contiene il tuo database.

Prima di iniziare

Configura un account di servizio gestito dall'utente per la tua VM:

Per completare la configurazione delle policy IAM per l'account di servizio Compute Engine, segui le istruzioni riportate nelle sezioni Configurare le credenziali.

Connessione da Cloud Run

Puoi autenticarti e connetterti al tuo database utilizzando un service account Cloud Run. Per farlo, crea un criterio IAM per il progetto Google Cloud che contiene il tuo database.

Prima di iniziare

Per completare la configurazione delle policy IAM per l'account di servizio Cloud Run, segui le istruzioni riportate nelle sezioni Configurare le credenziali.

Configurare le credenziali

Per concedere all'account di servizio il ruolo roles/datastore.user per la lettura e la scrittura in Cloud Firestore, esegui questo comando:

gcloud projects add-iam-policy-binding PROJECT_NAME --member="SERVICE_ACCOUNT_EMAIL" --role=roles/datastore.user

Sostituisci quanto segue:

  • PROJECT_NAME: il nome del progetto.
  • SERVICE_ACCOUNT_EMAIL: l'indirizzo email del service account che hai creato.

Costruisci la stringa di connessione

Utilizza il seguente formato per creare la stringa di connessione:

mongodb://DATABASE_UID.LOCATION.firestore.goog:443/DATABASE_ID?loadBalanced=true&tls=true&retryWrites=false&authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:gcp,TOKEN_RESOURCE:FIRESTORE

Sostituisci quanto segue:

  • DATABASE_UID: il nome del progetto.
  • LOCATION: la posizione del database.
  • DATABASE_ID l'ID database.

Per ulteriori informazioni sul recupero dell'UID e della posizione, consulta Recuperare la stringa di connessione.

Connettiti con un token di accesso temporaneo

Puoi utilizzare un token di accesso temporaneo Google Cloud per eseguire strumenti di diagnostica come mongosh. Puoi utilizzare gcloud auth print-access-token per l'autenticazione con un token di accesso a breve termine. Questo token è valido per un'ora.

Ad esempio, utilizza il seguente comando per connetterti al tuo database con mongosh:

mongosh --tls \
      --username access_token --password $(gcloud auth print-access-token) \
      'mongodb://UID.LOCATION.firestore.goog:443/DATABASE_ID?loadBalanced=true&authMechanism=PLAIN&authSource=$external&retryWrites=false'

Sostituisci quanto segue:

  • DATABASE_UID: l'UID del database
  • LOCATION: la posizione del database
  • DATABASE_ID: un ID database