Authentifizierung und Verbindung zu einer Datenbank

Verbindungsanforderungen

Für Cloud Firestore-Clients ist Folgendes erforderlich:

  • Treiber müssen im load balanced-Modus verbunden werden. Dadurch wird verhindert, dass die Treiber versuchen, die genaue Servertopologie zu verstehen, mit der sie eine Verbindung herstellen.
  • Treiber müssen mit aktiviertem SSL verbunden werden.
  • Treiber müssen wiederholbare Schreibvorgänge deaktivieren. Cloud Firestore unterstützt keine wiederholbaren Schreibvorgänge. Sie müssen wiederholbare Lesevorgänge nicht deaktivieren, da sie unterstützt werden.

Verbindungsstring abrufen

Der Verbindungsstring der Datenbank hängt von der UID der Datenbank, dem Standort der Datenbank und dem Authentifizierungsmechanismus ab. In der folgenden Anleitung wird beschrieben, wie der Verbindungsstring gebildet wird.

Der genaue Verbindungsstring hängt vom Authentifizierungsmechanismus ab. Der Basisverbindungsstring hat jedoch das folgende Format:

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

Sie können den Basisverbindungsstring auf eine der folgenden Arten abrufen:

Firebase Console
  1. Rufen Sie in der Firebase Console die Seite Firestore Database auf.

    Zur Firestore-Datenbank

  2. Klicken Sie auf die Datenbank, die Sie authentifizieren möchten.
  3. Klicken Sie im Bereich Explorer auf Mehr anzeigen.
  4. Wählen Sie Verbindung mit MongoDB-Tools herstellen aus.
  5. Kopieren Sie den Verbindungsstring.
gcloud

Verwenden Sie gcloud firestore database describe, um die UID und die Standortinformationen abzurufen:

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

Ersetzen Sie DATABASE_ID durch die Datenbank-ID.

Die Ausgabe enthält den Standort und die UID der Datenbank. Verwenden Sie diese Informationen, um den Basisverbindungsstring zu erstellen.

Verwenden Sie den Basisverbindungsstring und eine der folgenden Methoden, um sich zu authentifizieren und eine Verbindung zu Ihrer Datenbank herzustellen:

Verbindung mit Nutzername und Passwort (SCRAM) herstellen

So erstellen Sie Nutzeranmeldedaten für Ihre Datenbank und stellen eine Verbindung zu Ihrer Datenbank her:

Hinweis

Bitten Sie Ihren Administrator, Ihnen die IAM-Rolle userCredsAdmin (roles/datastore.userCredsAdmin) für Ihre Datenbank zuzuweisen, um die Berechtigungen zu erhalten, die Sie zum Erstellen eines Nutzers benötigen. Weitere Informationen zum Zuweisen von Rollen finden Sie unter Zugriff auf Projekte, Ordner und Organisationen verwalten.

Sie können die erforderlichen Berechtigungen auch über benutzerdefinierte Rollen oder andere vordefinierte Rollen erhalten.

Nutzer erstellen und Verbindung zu einer Datenbank herstellen

Verwenden Sie eine der folgenden Methoden, um einen Nutzer für Ihre Cloud Firestore-Datenbank zu erstellen:

Firebase Console
  1. Rufen Sie in der Firebase Console die Seite Firestore Database auf.

    Zur Firestore-Datenbank

  2. Wählen Sie eine Datenbank aus der Liste der Datenbanken aus.
  3. Klicken Sie im Navigationsmenü auf Sicherheit.
  4. Klicken Sie auf Nutzer hinzufügen.
  5. Geben Sie einen Nutzernamen ein.
  6. Wählen Sie eine Rolle für den neuen Nutzer aus.
  7. Klicken Sie auf Nutzer hinzufügen.
  8. Das Passwort des neuen Nutzers wird im Bestätigungsdialogfeld angezeigt.

gcloud CLI
  1. Wenn Sie sich mit SCRAM authentifizieren möchten, müssen Sie zuerst Nutzeranmeldedaten erstellen. Führen Sie den Befehl gcloud firestore user-creds aus:
    gcloud firestore user-creds create USERNAME --database=DATABASE_ID
    Ersetzen Sie Folgendes:
    • USERNAME: der zu erstellende Nutzername.
    • DATABASE_ID: die Datenbank-ID.

    Die Ausgabe dieses Befehls enthält das Passwort des Nutzers.

    Die Ausgabe sollte so aussehen:

    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. Standardmäßig haben diese neuen Nutzeranmeldedaten keine Berechtigungen. Fügen Sie für Lese- und Schreibzugriff auf die Datenbank die Rolle roles/datastore.user für diese spezifische Datenbank hinzu:

    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"'
    Ersetzen Sie Folgendes:
Java

In diesem Abschnitt finden Sie ein Codebeispiel zum Erstellen von Nutzeranmeldedaten und zum Konfigurieren der IAM-Richtlinie mithilfe von Java-Clientbibliotheken für die Verwaltung. Im Beispiel wird die Firestore Admin Client-Bibliothek zum Erstellen eines Nutzernamens und eines Passworts sowie die Google Cloud Resource Manager-Bibliothek zum Konfigurieren von IAM verwendet.

Für Maven-Builds können Sie die folgenden Koordinaten verwenden:

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

Stellen Sie Nutzeranmeldedaten und eine IAM-Richtlinie bereit:

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

In diesem Abschnitt finden Sie ein Codebeispiel zum Erstellen von Nutzeranmeldedaten und zum Konfigurieren der IAM-Richtlinie mithilfe von Python-Clientbibliotheken für die Verwaltung. Im Beispiel wird die Google Cloud Firestore API-Clientbibliothek zum Erstellen eines Nutzernamens und eines Passworts verwendet. Die Google Cloud IAM API-Clientbibliothek und die Google Cloud Resource Manager API-Clientbibliothek werden zum Konfigurieren von IAM verwendet.

Die erforderlichen Python-Bibliotheken können mit dem pip-Tool installiert werden:

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

Stellen Sie Nutzeranmeldedaten und eine IAM-Richtlinie bereit:

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}]')

Verwenden Sie den folgenden Verbindungsstring, um mit SCRAM eine Verbindung zu Ihrer Datenbank herzustellen:

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

Ersetzen Sie Folgendes:

  • USERNAME: der Nutzername.
  • PASSWORD: das Passwort, das Sie für diesen Nutzer generiert haben.
  • UID: die UID der Datenbank. Beispiel: f116f93a-519c-208a-9a72-3ef6c9a1f081
  • LOCATION: der Standort der Datenbank.
  • DATABASE_ID: die Datenbank-ID.

Verbindung mit der Google Auth-Bibliothek herstellen

Im folgenden Codebeispiel wird ein OIDC-Callback-Handler mit der OAuth-Standardbibliothek von Google Cloud registriert.

Mit dieser Bibliothek können Sie verschiedene Arten der Authentifizierung verwenden (Standardanmeldedaten für Anwendungen, Workload Identity-Föderation).

Dazu muss die Authentifizierungsbibliothek als Abhängigkeit hinzugefügt werden:

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

Im folgenden Codebeispiel wird gezeigt, wie Sie eine Verbindung herstellen:

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

Ersetzen Sie Folgendes:

  • DATABASE_UID: die UID der Datenbank. Beispiel: f116f93a-519c-208a-9a72-3ef6c9a1f081
  • LOCATION: der Standort Ihrer Datenbank.
  • DATABASE_ID: die Datenbank-ID.

Verbindung über eine Google Cloud-Computing-Umgebung herstellen

In diesem Abschnitt wird beschrieben, wie Sie von einer Google Cloud-Computing-Umgebung wie Compute Engine oder einem Cloud Run-Dienst oder -Job eine Verbindung zu Cloud Firestore herstellen.

Verbindung von einer Compute Engine-VM herstellen

Sie können sich mit einem Compute Engine-Dienstkonto authentifizieren und eine Verbindung zu Ihrer Datenbank herstellen. Erstellen Sie dazu eine IAM-Richtlinie für das Projekt Google Cloud, das Ihre Datenbank enthält.

Hinweis

Konfigurieren Sie ein nutzerverwaltetes Dienstkonto für Ihre VM:

Folgen Sie der Anleitung im Abschnitt Anmeldedaten konfigurieren, um die IAM-Richtlinienkonfiguration für Ihr Compute Engine-Dienstkonto abzuschließen.

Verbindung von Cloud Run herstellen

Sie können sich mit einem Cloud Run-Dienstkonto authentifizieren und eine Verbindung zu Ihrer Datenbank herstellen. Erstellen Sie dazu eine IAM-Richtlinie für das Projekt Google Cloud, das Ihre Datenbank enthält.

Hinweis

Folgen Sie der Anleitung im Abschnitt Anmeldedaten konfigurieren, um die IAM-Richtlinienkonfiguration für Ihr Cloud Run-Dienstkonto abzuschließen.

Anmeldedaten konfigurieren

Führen Sie den folgenden Befehl aus, um dem Dienstkonto die Rolle roles/datastore.user für Lese- und Schreibzugriff auf Cloud Firestore zuzuweisen:

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

Ersetzen Sie Folgendes:

  • PROJECT_NAME: Name Ihres Projekts
  • SERVICE_ACCOUNT_EMAIL: die E-Mail-Adresse des von Ihnen erstellten Dienstkontos.

Verbindungsstring erstellen

Verwenden Sie das folgende Format, um den Verbindungsstring zu erstellen:

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

Ersetzen Sie Folgendes:

  • DATABASE_UID: die UID der Datenbank. Beispiel: f116f93a-519c-208a-9a72-3ef6c9a1f081
  • LOCATION: der Standort Ihrer Datenbank.
  • DATABASE_ID: die Datenbank-ID.

Weitere Informationen zum Abrufen der UID und des Standorts finden Sie unter Verbindungsstring abrufen.

Mit einem temporären Zugriffstoken verbinden

Sie können ein temporäres Google Cloud-Zugriffstoken verwenden, um Diagnosetools wie mongosh auszuführen. Sie können gcloud auth print-access-token verwenden, um sich mit einem kurzfristigen Zugriffstoken zu authentifizieren. Dieses Token ist eine Stunde lang gültig.

Verwenden Sie beispielsweise den folgenden Befehl, um mit mongosh eine Verbindung zu Ihrer Datenbank herzustellen:

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'

Ersetzen Sie Folgendes:

  • DATABASE_UID: die UID der Datenbank. Beispiel: f116f93a-519c-208a-9a72-3ef6c9a1f081
  • LOCATION: der Standort der Datenbank
  • DATABASE_ID: eine Datenbank-ID