Authentifier et se connecter à une base de données

Ne concerne que l'édition Cloud Firestore Enterprise.

Exigences de connexion

Les éléments suivants sont requis pour les clients Cloud Firestore compatibles avec MongoDB :

  • Les pilotes doivent se connecter en mode load balanced. Cela empêche les pilotes d'essayer de comprendre la topologie exacte du serveur auquel ils se connectent.
  • Les pilotes doivent se connecter avec le protocole SSL activé.
  • Les pilotes doivent désactiver les écritures réessayables. Cloud Firestore compatible avec MongoDB ne prend pas en charge les écritures pouvant être réessayées. Vous n'avez pas besoin de désactiver les lectures pouvant être relues, car elles sont prises en charge.

Récupérer la chaîne de connexion

La chaîne de connexion à la base de données dépend de l'UID de la base de données, de son emplacement et du mécanisme d'authentification. Les instructions suivantes décrivent la façon dont la chaîne de connexion est formée.

La chaîne de connexion exacte dépend du mécanisme d'authentification, mais la chaîne de connexion de base utilise le format suivant :

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

Vous pouvez obtenir la chaîne de connexion de base de l'une des manières suivantes :

Console Firebase
  1. Dans la console Firebase, accédez à la page Base de données Firestore.

    Accéder à la base de données Firestore

  2. Cliquez sur la base de données que vous souhaitez authentifier.
  3. Dans le panneau Explorateur, cliquez sur Afficher plus.
  4. Sélectionnez Se connecter à l'aide des outils MongoDB.
  5. Copiez la chaîne de connexion.
gcloud

Utilisez gcloud firestore database describe pour récupérer l'UID et les informations de localisation :

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

Remplacez DATABASE_ID par l'ID de la base de données.

La sortie inclut l'emplacement et l'UID de la base de données. Utilisez ces informations pour construire la chaîne de connexion de base.

Utilisez la chaîne de connexion de base et l'une des méthodes suivantes pour vous authentifier et vous connecter à votre base de données :

Se connecter avec un nom d'utilisateur et un mot de passe (SCRAM)

Suivez ces étapes pour créer des identifiants utilisateur pour votre base de données et vous y connecter.

Avant de commencer

Pour obtenir les autorisations nécessaires pour créer un utilisateur, demandez à votre administrateur de vous accorder le rôle IAM userCredsAdmin (roles/datastore.userCredsAdmin) sur votre base de données. Pour en savoir plus sur l'attribution de rôles, consultez Gérer l'accès aux projets, aux dossiers et aux organisations.

Vous pouvez également obtenir les autorisations requises grâce aux rôles personnalisés ou à d'autres rôles prédéfinis.

Créer un utilisateur et se connecter à une base de données

Pour créer un utilisateur pour votre base de données Cloud Firestore compatible avec MongoDB, utilisez l'une des méthodes suivantes :

Console Google Cloud
  1. Dans la console Google Cloud, accédez à la page Base de données.

    Accéder à la page "Bases de données"

  2. Sélectionnez une base de données dans la liste.
  3. Dans le menu de navigation, cliquez sur Authentification.
  4. Cliquez sur Ajouter un utilisateur.
  5. Indiquez un nom d'utilisateur.
  6. Sélectionnez un rôle pour le nouvel utilisateur.
  7. Cliquez sur Ajouter.

    Le mot de passe du nouvel utilisateur s'affiche dans la boîte de dialogue de confirmation.

gcloud CLI
  1. Pour vous authentifier avec SCRAM, vous devez d'abord créer un identifiant utilisateur. Exécutez la commande gcloud firestore user-creds :
    gcloud firestore user-creds create USERNAME --database=DATABASE_ID
    Remplacez les éléments suivants :
    • USERNAME : nom d'utilisateur à créer.
    • DATABASE_ID : ID de la base de données.

    Le résultat de cette commande inclut le mot de passe de l'utilisateur.

    Le résultat se présente comme suit :

    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. Par défaut, ces nouvelles identifiants utilisateur ne disposent d'aucune autorisation. Pour obtenir un accès en lecture et en écriture à la base de données, ajoutez le rôle roles/datastore.user pour cette base de données spécifique :

    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"'
    Remplacez les éléments suivants :
Java

Cette section fournit un exemple de code pour créer des identifiants utilisateur et configurer la stratégie IAM à l'aide des bibliothèques clientes d'administration Java. L'exemple utilise la bibliothèque Firestore Admin Client pour créer un nom d'utilisateur et un mot de passe, et la bibliothèque Google Cloud Resource Manager pour configurer IAM.

Pour les builds Maven, vous pouvez utiliser les coordonnées suivantes :

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

Provisionnez des identifiants utilisateur et une stratégie 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

Cette section fournit un exemple de code pour créer des identifiants utilisateur et configurer la stratégie IAM à l'aide des bibliothèques clientes d'administration Python. L'exemple utilise la bibliothèque cliente de l'API Google Cloud Firestore pour créer un nom d'utilisateur et un mot de passe, ainsi que la bibliothèque cliente de l'API Google Cloud IAM et la bibliothèque cliente de l'API Google Cloud Resource Manager pour configurer IAM.

Les bibliothèques Python requises peuvent être installées avec l'outil pip :

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

Provisionnez des identifiants utilisateur et une stratégie 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}]')

Utilisez la chaîne de connexion suivante pour vous connecter à votre base de données avec SCRAM :

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

Remplacez les éléments suivants :

  • USERNAME : nom d'utilisateur.
  • PASSWORD : mot de passe que vous avez généré pour cet utilisateur.
  • UID : UID de la base de données.
  • LOCATION : emplacement de la base de données.
  • DATABASE_ID : ID de la base de données.

Se connecter à la bibliothèque Google Auth

L'exemple de code suivant enregistre un gestionnaire de rappel OIDC et utilise la bibliothèque OAuth standard Google Cloud.

Cette bibliothèque vous permet d'utiliser différents types d'authentification (identifiants par défaut de l'application, fédération d'identité de charge de travail).

Pour cela, vous devez ajouter la bibliothèque d'authentification en tant que dépendance :

// 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'

L'exemple de code suivant montre comment se connecter :

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);
}

Remplacez les éléments suivants :

  • DATABASE_UID : nom de votre projet.
  • LOCATION : emplacement de votre base de données.
  • DATABASE_ID, l'ID de la base de données.

Se connecter depuis un environnement de calcul Google Cloud

Cette section décrit comment se connecter à Cloud Firestore avec compatibilité MongoDB à partir d'un environnement de calcul Google Cloud, tel que Compute Engine ou un service ou job Cloud Run.

Se connecter à partir d'une VM Compute Engine

Vous pouvez vous authentifier et vous connecter à votre base de données à l'aide d'un compte de service Compute Engine. Pour ce faire, créez une stratégie IAM pour le projet Google Cloud qui contient votre base de données.

Avant de commencer

Configurez un compte de service géré par l'utilisateur pour votre VM :

Suivez les instructions de la section Configurer les identifiants pour terminer la configuration de la stratégie IAM pour votre compte de service Compute Engine.

Se connecter depuis Cloud Run

Vous pouvez vous authentifier et vous connecter à votre base de données à l'aide d'un compte de service Cloud Run. Pour ce faire, créez une stratégie IAM pour le projet Google Cloud qui contient votre base de données.

Avant de commencer

Suivez les instructions de la section Configurer les identifiants pour terminer la configuration de la stratégie IAM pour votre compte de service Cloud Run.

Configurer les identifiants

Pour accorder au compte de service le rôle roles/datastore.user en lecture et en écriture sur Cloud Firestore, exécutez la commande suivante :

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

Remplacez les éléments suivants :

  • PROJECT_NAME : nom de votre projet.
  • SERVICE_ACCOUNT_EMAIL : adresse e-mail du compte de service que vous avez créé.

Construire la chaîne de connexion

Utilisez le format suivant pour créer la chaîne de connexion :

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

Remplacez les éléments suivants :

  • DATABASE_UID : nom de votre projet.
  • LOCATION : emplacement de votre base de données.
  • DATABASE_ID, l'ID de la base de données.

Pour savoir comment récupérer l'UID et l'emplacement, consultez Récupérer la chaîne de connexion.

Se connecter avec un jeton d'accès temporaire

Vous pouvez utiliser un jeton d'accès Google Cloud temporaire pour exécuter des outils de diagnostic tels que mongosh. Vous pouvez utiliser gcloud auth print-access-token pour vous authentifier avec un jeton d'accès à court terme. Ce jeton est valide pendant une heure.

Par exemple, utilisez la commande suivante pour vous connecter à votre base de données avec 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'

Remplacez les éléments suivants :

  • DATABASE_UID : UID de la base de données
  • LOCATION : emplacement de la base de données
  • DATABASE_ID : ID de la base de données