Autorisierte Ansichten und materialisierte Ansichten

In diesem Dokument erfahren Sie, wie Sie autorisierte Ansichten und materialisierte Ansichten in BigQuery erstellen.

Mit autorisierten Ansichten und autorisierten materialisierten Ansichten können Sie Abfrageergebnisse für bestimmte Nutzer und Gruppen freigeben, ohne ihnen Zugriff auf die zugrunde liegenden Quelldaten zu gewähren. Die Ansicht oder materialisierte Ansicht erhält Zugriff auf die Daten statt auf den Nutzer. Sie können auch die SQL-Abfrage verwenden, mit der die Ansicht oder die materialisierte Ansicht erstellt wird, um die Spalten und Felder einzuschränken, die Nutzer abfragen können.

Wenn Sie eine autorisierte Ansicht oder eine materialisierte Ansicht in einem anderen Dataset erstellen, müssen sich sowohl das Quelldaten- als auch das autorisierte Ansichts-Dataset am selben regionalen Standort befinden.

Informationen zum Autorisieren aller Ansichten in einem Dataset anstelle der Autorisierung einzelner Ansichten finden Sie unter Autorisierte Datasets.

Hinweis

Weisen Sie IAM-Rollen (Identity and Access Management) zu, die Nutzern die erforderlichen Berechtigungen zum Ausführen der einzelnen Aufgaben in diesem Dokument gewähren.

Erforderliche Berechtigungen

Zum Erstellen oder Aktualisieren einer autorisierten Ansicht benötigen Sie Berechtigungen für das Dataset, das die Ansicht enthält, und für das Dataset, das Zugriff auf die Ansicht gewährt.

Berechtigungen für das Dataset, das die Ansicht enthält

Ansichten werden in BigQuery als Tabellenressourcen behandelt. Daher sind für das Erstellen einer Ansicht dieselben Berechtigungen erforderlich wie für das Erstellen einer Tabelle. Sie benötigen außerdem Berechtigungen zum Abfragen aller Tabellen, auf die die SQL-Abfrage der Ansicht verweist.

Sie benötigen die IAM-Berechtigung bigquery.tables.create, um eine Ansicht zu erstellen. Die vordefinierte IAM-Rolle roles/bigquery.dataEditor enthält die Berechtigungen, die Sie zum Erstellen einer Konfiguration benötigen.

Wenn Sie die Berechtigung bigquery.datasets.create haben, können Sie außerdem Ansichten in den von Ihnen erstellten Datasets erstellen. Wenn Sie eine Ansicht für Daten erstellen möchten, deren Inhaber Sie nicht sind, benötigen Sie die Berechtigung bigquery.tables.getData für diese Tabelle.

Weitere Informationen zu IAM-Rollen und Berechtigungen in BigQuery finden Sie unter Vordefinierte Rollen und Berechtigungen.

Berechtigungen für das Dataset, das Zugriff auf die Ansicht gewährt

Zum Aktualisieren von Dataset-Attributen benötigen Sie die folgenden IAM-Berechtigungen:

  • bigquery.datasets.update
  • bigquery.datasets.setIamPolicy (nur erforderlich, wenn Dataset-Zugriffssteuerungen in der Google Cloud Console aktualisiert werden)

Die vordefinierte IAM-Rolle roles/bigquery.dataOwner enthält die Berechtigungen, die Sie zum Aktualisieren von Dataset-Attributen benötigen.

Wenn Sie die Berechtigung bigquery.datasets.create haben, können Sie außerdem Attribute der von Ihnen erstellten Datasets aktualisieren.

Weitere Informationen zu IAM-Rollen und Berechtigungen in BigQuery finden Sie unter Vordefinierte Rollen und Berechtigungen.

Ansicht autorisieren

So gewähren Sie einer Ansicht Zugriff auf ein Dataset:

Console

  1. Rufen Sie in der Google Cloud Console die Seite "BigQuery" auf.

    BigQuery aufrufen

  2. Maximieren Sie im Bereich Explorer Ihr Projekt und wählen Sie ein Dataset aus.

  3. Klicken Sie auf Aktionen anzeigen und dann auf Öffnen.

  4. Klicken Sie im Bereich Dataset-Informationen auf Freigabe und wählen Sie Ansichten autorisieren aus.

  5. Geben Sie bei Ansicht autorisieren den Namen der zu autorisierenden Ansicht ein.

  6. Klicken Sie auf Autorisierung hinzufügen.

  7. Klicken Sie auf Schließen.

bq

  1. Schreiben Sie die vorhandenen Dataset-Informationen (einschließlich Zugriffssteuerungen) mit dem Befehl bq show in eine JSON-Datei. Wenn sich das Dataset in einem anderen Projekt als Ihrem Standardprojekt befindet, fügen Sie dem Dataset-Namen die Projekt-ID im folgenden Format hinzu: project_id:dataset.

    bq show \
    --format=prettyjson \
    project_id:dataset > path_to_file
    

    Dabei gilt:

    • project_id ist die Projekt-ID.
    • dataset ist der Name des Datasets.
    • path_to_file ist der Pfad zur JSON-Datei auf Ihrem lokalen Computer.

    Beispiele:

    Geben Sie den folgenden Befehl ein, um die Zugriffssteuerungen für mydataset in eine JSON-Datei zu schreiben. mydataset befindet sich in Ihrem Standardprojekt.

    bq show --format=prettyjson mydataset > /tmp/mydataset.json
    

    Geben Sie den folgenden Befehl ein, um die Zugriffssteuerungen für mydataset in eine JSON-Datei zu schreiben. mydataset befindet sich in myotherproject.

    bq show --format=prettyjson \
    myotherproject:mydataset > /tmp/mydataset.json
    
  2. Fügen Sie die autorisierte Ansicht zum Bereich „Zugriff“ der JSON-Datei hinzu.

    Der Abschnitt „access“ der JSON-Datei eines Datasets sieht zum Beispiel so aus:

    {
     "access": [
      {
       "role": "READER",
       "specialGroup": "projectReaders"
      },
      {
       "role": "WRITER",
       "specialGroup": "projectWriters"
      },
      {
       "role": "OWNER",
       "specialGroup": "projectOwners"
      }
      {
       "role": "READER",
       "specialGroup": "allAuthenticatedUsers"
      }
      {
       "role": "READER",
       "domain": "[DOMAIN_NAME]"
      }
      {
       "role": "WRITER",
       "userByEmail": "[USER_EMAIL]"
      }
      {
       "role": "READER",
       "groupByEmail": "[GROUP_EMAIL]"
      },
      {
       "view":{
       "datasetId": "[DATASET_NAME]",
       "projectId": "[PROJECT_NAME]",
       "tableId": "[VIEW_NAME]"
       }
      }
     ],
    }
    

  3. Wenn die Änderungen abgeschlossen sind, führen Sie den Befehl bq update aus und fügen mit dem Flag --source die JSON-Datei hinzu. Wenn sich das Dataset in einem anderen Projekt als Ihrem Standardprojekt befindet, fügen Sie dem Dataset-Namen die Projekt-ID im folgenden Format hinzu: project_id:dataset.

    bq update \
    --source path_to_file \
    project_id:dataset
    

    Dabei gilt:

    • path_to_file ist der Pfad zur JSON-Datei auf Ihrem lokalen Computer.
    • project_id ist die Projekt-ID.
    • dataset ist der Name des Datasets.

    Beispiele:

    Geben Sie den folgenden Befehl ein, um die Zugriffssteuerungen für mydataset zu aktualisieren. mydataset befindet sich in Ihrem Standardprojekt.

     bq update --source /tmp/mydataset.json mydataset
    

    Geben Sie den folgenden Befehl ein, um die Zugriffssteuerungen für mydataset zu aktualisieren. mydataset befindet sich in myotherproject.

     bq update --source /tmp/mydataset.json myotherproject:mydataset
    
  4. Geben Sie den Befehl show noch einmal ein, ohne die Informationen in eine Datei zu schreiben, um die Änderungen der Zugriffssteuerung zu prüfen.

    bq show --format=prettyjson [DATASET]
    

    oder

    bq show --format=prettyjson [PROJECT_ID]:[DATASET]
    

API

Rufen Sie die Methode datasets.patch auf und verwenden Sie das Attribut access, um die Zugriffssteuerungen zu aktualisieren. Weitere Informationen zu Datasets.

Da die Methode datasets.update die gesamte Dataset-Ressource ersetzt, ist datasets.patch die bevorzugte Methode zum Aktualisieren von Zugriffssteuerungen.

Go

Bevor Sie dieses Beispiel anwenden, folgen Sie den Schritten zur Einrichtung von Go in der BigQuery-Kurzanleitung zur Verwendung von Clientbibliotheken. Weitere Angaben finden Sie in der Referenzdokumentation zur BigQuery Go API.

Richten Sie zur Authentifizierung bei BigQuery die Standardanmeldedaten für Anwendungen ein. Weitere Informationen finden Sie unter Authentifizierung für Clientbibliotheken einrichten.

import (
	"context"
	"fmt"

	"cloud.google.com/go/bigquery"
)

// updateViewDelegated demonstrates the setup of an authorized view, which allows access to a view's results
// without the caller having direct access to the underlying source data.
func updateViewDelegated(projectID, srcDatasetID, viewDatasetID, viewID string) error {
	// projectID := "my-project-id"
	// srcDatasetID := "sourcedata"
	// viewDatasetID := "views"
	// viewID := "myview"
	ctx := context.Background()
	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	srcDataset := client.Dataset(srcDatasetID)
	viewDataset := client.Dataset(viewDatasetID)
	view := viewDataset.Table(viewID)

	// First, we'll add a group to the ACL for the dataset containing the view.  This will allow users within
	// that group to query the view, but they must have direct access to any tables referenced by the view.
	vMeta, err := viewDataset.Metadata(ctx)
	if err != nil {
		return err
	}
	vUpdateMeta := bigquery.DatasetMetadataToUpdate{
		Access: append(vMeta.Access, &bigquery.AccessEntry{
			Role:       bigquery.ReaderRole,
			EntityType: bigquery.GroupEmailEntity,
			Entity:     "example-analyst-group@google.com",
		}),
	}
	if _, err := viewDataset.Update(ctx, vUpdateMeta, vMeta.ETag); err != nil {
		return err
	}

	// Now, we'll authorize a specific view against a source dataset, delegating access enforcement.
	// Once this has been completed, members of the group previously added to the view dataset's ACL
	// no longer require access to the source dataset to successfully query the view.
	srcMeta, err := srcDataset.Metadata(ctx)
	if err != nil {
		return err
	}
	srcUpdateMeta := bigquery.DatasetMetadataToUpdate{
		Access: append(srcMeta.Access, &bigquery.AccessEntry{
			EntityType: bigquery.ViewEntity,
			View:       view,
		}),
	}
	if _, err := srcDataset.Update(ctx, srcUpdateMeta, srcMeta.ETag); err != nil {
		return err
	}
	return nil
}

Java

Bevor Sie dieses Beispiel anwenden, folgen Sie den Schritten zur Einrichtung von Java in der BigQuery-Kurzanleitung zur Verwendung von Clientbibliotheken. Weitere Angaben finden Sie in der Referenzdokumentation zur BigQuery Java API.

Richten Sie zur Authentifizierung bei BigQuery die Standardanmeldedaten für Anwendungen ein. Weitere Informationen finden Sie unter Authentifizierung für Clientbibliotheken einrichten.

import com.google.cloud.bigquery.Acl;
import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.Dataset;
import com.google.cloud.bigquery.DatasetId;
import com.google.cloud.bigquery.Table;
import java.util.ArrayList;
import java.util.List;

// Sample to grant view access on dataset
public class GrantViewAccess {

  public static void runGrantViewAccess() {
    // TODO(developer): Replace these variables before running the sample.
    String srcDatasetId = "MY_DATASET_ID";
    String viewDatasetId = "MY_VIEW_DATASET_ID";
    String viewId = "MY_VIEW_ID";
    grantViewAccess(srcDatasetId, viewDatasetId, viewId);
  }

  public static void grantViewAccess(String srcDatasetId, String viewDatasetId, String viewId) {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      Dataset srcDataset = bigquery.getDataset(DatasetId.of(srcDatasetId));
      Dataset viewDataset = bigquery.getDataset(DatasetId.of(viewDatasetId));
      Table view = viewDataset.get(viewId);

      // First, we'll add a group to the ACL for the dataset containing the view. This will allow
      // users within that group to query the view, but they must have direct access to any tables
      // referenced by the view.
      List<Acl> viewAcl = new ArrayList<>();
      viewAcl.addAll(viewDataset.getAcl());
      viewAcl.add(Acl.of(new Acl.Group("example-analyst-group@google.com"), Acl.Role.READER));
      viewDataset.toBuilder().setAcl(viewAcl).build().update();

      // Now, we'll authorize a specific view against a source dataset, delegating access
      // enforcement. Once this has been completed, members of the group previously added to the
      // view dataset's ACL no longer require access to the source dataset to successfully query the
      // view
      List<Acl> srcAcl = new ArrayList<>();
      srcAcl.addAll(srcDataset.getAcl());
      srcAcl.add(Acl.of(new Acl.View(view.getTableId())));
      srcDataset.toBuilder().setAcl(srcAcl).build().update();
      System.out.println("Grant view access successfully");
    } catch (BigQueryException e) {
      System.out.println("Grant view access was not success. \n" + e.toString());
    }
  }
}

Python

Bevor Sie dieses Beispiel anwenden, folgen Sie den Schritten zur Einrichtung von Python in der BigQuery-Kurzanleitung zur Verwendung von Clientbibliotheken. Weitere Angaben finden Sie in der Referenzdokumentation zur BigQuery Python API.

Richten Sie zur Authentifizierung bei BigQuery die Standardanmeldedaten für Anwendungen ein. Weitere Informationen finden Sie unter Authentifizierung für Clientbibliotheken einrichten.

from google.cloud import bigquery

client = bigquery.Client()

# To use a view, the analyst requires ACLs to both the view and the source
# table. Create an authorized view to allow an analyst to use a view
# without direct access permissions to the source table.
view_dataset_id = "my-project.my_view_dataset"
# Make an API request to get the view dataset ACLs.
view_dataset = client.get_dataset(view_dataset_id)

analyst_group_email = "data_analysts@example.com"
access_entries = view_dataset.access_entries
access_entries.append(
    bigquery.AccessEntry("READER", "groupByEmail", analyst_group_email)
)
view_dataset.access_entries = access_entries

# Make an API request to update the ACLs property of the view dataset.
view_dataset = client.update_dataset(view_dataset, ["access_entries"])
print(f"Access to view: {view_dataset.access_entries}")

# Group members of "data_analysts@example.com" now have access to the view,
# but they require access to the source table to use it. To remove this
# restriction, authorize the view to access the source dataset.
source_dataset_id = "my-project.my_source_dataset"
# Make an API request to set the source dataset ACLs.
source_dataset = client.get_dataset(source_dataset_id)

view_reference = {
    "projectId": "my-project",
    "datasetId": "my_view_dataset",
    "tableId": "my_authorized_view",
}
access_entries = source_dataset.access_entries
access_entries.append(bigquery.AccessEntry(None, "view", view_reference))
source_dataset.access_entries = access_entries

# Make an API request to update the ACLs property of the source dataset.
source_dataset = client.update_dataset(source_dataset, ["access_entries"])
print(f"Access to source: {source_dataset.access_entries}")

Autorisierung für Ansicht entfernen

So entfernen Sie eine Autorisierung für eine Ansicht:

Console

  1. Rufen Sie in der Google Cloud Console die Seite "BigQuery" auf.

    BigQuery aufrufen

  2. Maximieren Sie im Bereich Explorer Ihr Projekt und wählen Sie ein Dataset aus.

  3. Klicken Sie auf Freigabe > Ansichten autorisieren.

  4. Klicken Sie auf Autorisierung entfernen.

  5. Klicken Sie auf Schließen.

Kontingente und Limits

  • Autorisierte Ansichten unterliegen den Dataset-Limits. Weitere Informationen finden Sie unter Dataset-Limits.
  • Wenn Sie eine autorisierte Ansicht entfernen, kann es bis zu 24 Stunden dauern, bis alle Verweise auf die Ansicht aus dem System entfernt wurden. Um Fehler zu vermeiden, warten Sie entweder 24 Stunden, bevor Sie den Namen einer entfernten Ansicht wiederverwenden, oder erstellen Sie einen eindeutigen Namen für Ihre Ansicht.

Zugriff auf Zeilenebene mithilfe einer Ansicht erzwingen

Mit Ansichten kann der Zugriff auf bestimmte Spalten (Felder) beschränkt werden. Wenn Sie den Zugriff auf einzelne Zeilen in einer Tabelle beschränken möchten, müssen Sie keine separaten Ansichten für jeden Nutzer oder jede Gruppe erstellen. Stattdessen können Sie die SESSION_USER()-Funktion verwenden, um die E-Mail-Adresse des aktuellen Nutzers zurückzugeben.

Wenn Sie verschiedenen Nutzern unterschiedliche Zeilen anzeigen möchten, fügen Sie der Tabelle ein weiteres Feld hinzu, das den Nutzer enthält, der die Zeile sehen darf. Erstellen Sie dann eine Ansicht, die die SESSION_USER()-Funktion nutzt. Im folgenden Beispiel werden die Nutzernamen im Feld allowed_viewer gespeichert:

SELECT
  COLUMN_1,
  COLUMN_2
FROM
  `dataset.view`
WHERE
  allowed_viewer = SESSION_USER()

Die Beschränkung bei diesem Ansatz besteht darin, dass Sie immer nur einem Nutzer gleichzeitig Zugriff gewähren können. Sie können sie dadurch umgehen, dass Sie allowed_viewer zu einem wiederkehrenden Feld machen. Mit diesem Ansatz können Sie eine Liste von Nutzern für jede Zeile angeben. Aber auch wenn Sie ein wiederkehrendes Feld verwenden, müssen Sie bei der Speicherung von Nutzernamen in der Tabelle manuell die einzelnen Nutzer mit Zugriff auf die einzelnen Zeilen erfassen.

Füllen Sie stattdessen das Feld allowed_viewer mit Gruppennamen und erstellen Sie eine separate Tabelle, die den Nutzern Gruppen zuordnet. Die Tabelle, die Gruppen zu Nutzern zuweist, muss über ein Schema verfügen, das Gruppen- und Nutzernamen speichert. Beispiel: {group:string, user_name:string}. So können Sie die Nutzer- und Gruppeninformationen getrennt von der Tabelle verwalten, die die Daten enthält.

Wenn die Zuordnungstabelle den Namen private.access_control hat, lautet die SQL-Abfrage zum Erstellen der autorisierten Ansicht:

SELECT
  c.customer,
  c.id
FROM
  `private.customers` c
INNER JOIN (
  SELECT
    group
  FROM
    `private.access_control`
  WHERE
    SESSION_USER() = user_name) g
ON
  c.allowed_group = g.group

Nächste Schritte