Autorisierte Ansichten erstellen

In diesem Dokument wird beschrieben, wie Sie autorisierte Ansichten in BigQuery erstellen.

Eine autorisierte Ansicht können Sie in BigQuery auf folgende Weise erstellen:

  • Mit der Cloud Console
  • Mit dem Befehl bq mk des bq-Befehlszeilentools
  • Durch Aufruf der API-Methode tables.insert
  • Mithilfe der Clientbibliotheken

Übersicht

Wenn einer Ansicht Zugriff auf ein Dataset gewährt wird, spricht man auch vom Erstellen einer autorisierten Ansicht in BigQuery. Mit einer autorisierten Ansicht können Sie Abfrageergebnisse mit bestimmten Nutzern und Gruppen teilen, ohne diesen Zugriff auf die zugrunde liegenden Quelldaten zu erteilen. Sie können auch die SQL-Abfrage der Ansicht verwenden, um die Spalten (Felder) einzuschränken, die die Nutzer abfragen können.

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

Eine Anleitung zum Erstellen einer autorisierten Ansicht finden Sie unter Autorisierte Ansicht erstellen.

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.

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. Zum Erstellen einer Ansicht benötigen Sie mindestens Berechtigungen des Typs bigquery.tables.create. Die folgenden vordefinierten IAM-Rollen enthalten bigquery.tables.create-Berechtigungen:

  • bigquery.dataEditor
  • bigquery.dataOwner
  • bigquery.admin

Wenn ein Nutzer mit Berechtigungen vom Typ bigquery.datasets.create ein Dataset erstellt, hat er dafür außerdem bigquery.dataOwner-Zugriff. Mit bigquery.dataOwner-Zugriff haben Nutzer die Möglichkeit, Ansichten im Dataset zu erstellen.

Wenn Sie eine Ansicht für Daten erstellen möchten, die Ihnen nicht gehören, benötigen Sie für die Tabelle Berechtigungen des Typs bigquery.jobs.create.

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

Dataset, das Zugriff auf die Ansicht gewährt

Sie benötigen mindestens die Berechtigungen bigquery.datasets.update und bigquery.datasets.get, um Dataset-Attribute zu aktualisieren. Diese vordefinierten IAM-Rollen enthalten die Berechtigungen bigquery.datasets.update und bigquery.datasets.get:

  • bigquery.dataOwner
  • bigquery.admin

Wenn ein Nutzer mit Berechtigungen vom Typ bigquery.datasets.create ein Dataset erstellt, hat er dafür außerdem bigquery.dataOwner-Zugriff. Mit bigquery.dataOwner-Zugriff haben Nutzer die Möglichkeit, Attribute für die von ihnen erstellten Datasets zu erstellen.

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

Ansichten Zugriff auf Datasets gewähren

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

Console

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

  2. Maximieren Sie die Option Aktionen und klicken Sie auf Öffnen.

  3. Klicken Sie im Detailbereich auf Dataset freigeben.

  4. Wählen Sie im Bereich Dataset-Berechtigungen den Tab Autorisierte Ansichten aus.

  5. Im Abschnitt Autorisierte Ansicht teilen:

    • Prüfen Sie unter Projekt auswählen den Projektnamen. Wenn sich die Ansicht in einem anderen Projekt befindet, müssen Sie dieses auswählen.
    • Wählen Sie unter Dataset auswählen das Dataset aus, das die Ansicht enthält.
    • Wählen Sie unter Ansicht auswählen die Ansicht aus, die Sie autorisieren möchten.
  6. Klicken Sie auf Hinzufügen und dann auf Fertig.

bq

  1. Schreiben Sie die vorhandenen Dataset-Informationen (einschließlich Zugriffssteuerungen) mit dem Befehl 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 gehört zu 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 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 gehört zu 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 finden Sie unter 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 ausprobieren, 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.

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 ausprobieren, folgen Sie den Schritten zur Einrichtung von Java in der BigQuery-Kurzanleitung: Clientbibliotheken verwenden. Weitere Informationen finden Sie in der Referenzdokumentation zur BigQuery Java API.

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 ausprobieren, folgen Sie den Schritten zur Einrichtung von Python in der BigQuery-Kurzanleitung: Clientbibliotheken verwenden. Weitere Informationen finden Sie in der Referenzdokumentation zur  Python API.

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

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. Es ist möglich, für jede Zeile eine Liste von Nutzern anzugeben. Sie müssen aber auch bei der Verwendung eines wiederholten Felds manuell einzeln die Nutzer herausfinden, die Zugriff auf die jeweiligen Zeilen haben.

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

Tipp