Visualizzazioni autorizzate e viste materializzate

Questo documento descrive come creare viste autorizzate e viste materializzate in in BigQuery.

Le viste autorizzate e quelle materializzate autorizzate ti consentono di condividere i risultati delle query con determinati utenti e gruppi senza concedere loro l'accesso ai i dati di origine. Alla vista o vista materializzata viene concesso l'accesso ai dati, anziché all'utente. Puoi anche utilizzare la query SQL che crea la vista vista materializzata per limitare le colonne e i campi che gli utenti possono query.

Quando si effettua una vista autorizzata o una vista materializzata in un altro set di dati, il set di dati dei dati di origine e quello della vista autorizzata devono trovarsi nella stessa regione location.

Per informazioni su come autorizzare tutte le viste in un set di dati, anziché l'autorizzazione di singole viste, Set di dati autorizzati.

Prima di iniziare

Concede ruoli IAM (Identity and Access Management) che concedono agli utenti le autorizzazioni necessarie per eseguire ciascuna attività in questo documento.

Autorizzazioni obbligatorie

Per creare o aggiornare una vista autorizzata, devi disporre delle autorizzazioni per il set di dati contiene la vista e il set di dati che le fornisce.

Autorizzazioni sul set di dati che contiene la vista

Le viste vengono trattate come risorse di tabella in BigQuery, quindi la creazione di un richiede le stesse autorizzazioni della creazione di una tabella. Devi inoltre avere autorizzazioni per eseguire query sulle tabelle a cui fa riferimento la query SQL della vista.

Per creare una vista, devi disporre di IAM bigquery.tables.create autorizzazione. Il ruolo IAM predefinito roles/bigquery.dataEditor include le autorizzazioni necessarie per creare una vista.

Inoltre, se disponi dell'autorizzazione bigquery.datasets.create, puoi e creare viste nei set di dati da te creati. Per creare una vista per i dati che non sono proprietari, devi disporre dell'autorizzazione bigquery.tables.getData per la tabella.

Per ulteriori informazioni su ruoli e autorizzazioni IAM in BigQuery, vedi Ruoli e ruoli predefiniti autorizzazioni.

Autorizzazioni sul set di dati che consente l'accesso alla vista

Per aggiornare le proprietà del set di dati, devi disporre delle seguenti autorizzazioni IAM:

  • bigquery.datasets.update
  • bigquery.datasets.setIamPolicy (richiesto solo durante l'aggiornamento dell'accesso al set di dati) nella console Google Cloud)

Il ruolo IAM predefinito di roles/bigquery.dataOwner include le autorizzazioni necessarie per aggiornare le proprietà del set di dati.

Inoltre, se disponi dell'autorizzazione bigquery.datasets.create, puoi aggiornare le proprietà dei set di dati che crei.

Per ulteriori informazioni su ruoli e autorizzazioni IAM in BigQuery, vedi Autorizzazioni e ruoli predefiniti.

Autorizzare una visualizzazione

Per concedere l'accesso in visualizzazione a un set di dati:

Console

  1. Vai alla pagina BigQuery nella console Google Cloud.

    Vai a BigQuery

  2. Nel riquadro Explorer, espandi il progetto e seleziona un set di dati.

  3. Clic Visualizza le azioni e fai clic su Apri.

  4. Nel riquadro Informazioni sul set di dati, fai clic su Condivisione e seleziona Autorizza visualizzazioni.

  5. In Autorizza vista, digita il nome della vista da autorizzare.

  6. Fai clic su Aggiungi autorizzazione.

  7. Fai clic su Chiudi.

bq

  1. Scrivi le informazioni esistenti del set di dati (inclusi i controlli di accesso) in un file JSON utilizzando Comando bq show. Se il set di dati si trova in un progetto diverso rispetto al progetto predefinito, aggiungi l'ID progetto al nome del set di dati nella nel seguente formato: project_id:dataset.

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

    Dove:

    • project_id è l'ID progetto.
    • dataset è il nome del tuo set di dati.
    • path_to_file è il percorso del file JSON sul tuo computer in una macchina virtuale.

    Esempi:

    Inserisci il comando seguente per scrivere i controlli di accesso per mydataset in un file JSON. mydataset è nel tuo progetto predefinito.

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

    Inserisci il comando seguente per scrivere i controlli di accesso per mydataset in un file JSON. mydataset è a myotherproject.

    bq show --format=prettyjson \
    myotherproject:mydataset > /tmp/mydataset.json
    
  2. Aggiungi la vista autorizzata all'accesso del file JSON.

    Ad esempio, la sezione di accesso del file JSON di un set di dati potrebbe essere le seguenti:

    {
     "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. Una volta apportate le modifiche, utilizza la bq update e includerai il comando con il flag --source. Se il set di dati si trova in un progetto diverso rispetto al progetto predefinito, aggiungi l'ID progetto al nome del set di dati nella nel seguente formato: project_id:dataset.

    bq update \
    --source path_to_file \
    project_id:dataset
    

    Dove:

    • path_to_file è il percorso del file JSON sul tuo computer in una macchina virtuale.
    • project_id è l'ID progetto.
    • dataset è il nome del tuo set di dati.

    Esempi:

    Inserisci il comando seguente per aggiornare i controlli dell'accesso per mydataset. mydataset è nel tuo progetto predefinito.

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

    Inserisci il comando seguente per aggiornare i controlli dell'accesso per mydataset. mydataset è a myotherproject.

     bq update --source /tmp/mydataset.json myotherproject:mydataset
    
  4. Per verificare le modifiche apportate al controllo dell'accesso, inserisci di nuovo il comando show senza scrivere le informazioni in un file.

    bq show --format=prettyjson [DATASET]
    

    o

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

API

Chiama il datasets.patch e utilizza la proprietà access per aggiornare i controlli di accesso. Per per saperne di più, consulta Set di dati.

Poiché il metodo datasets.update sostituisce l'intera risorsa del set di dati, datasets.patch è il metodo preferito per l'aggiornamento dei controlli dell'accesso.

Vai

Prima di provare questo esempio, segui le istruzioni per la configurazione di Go nel Guida rapida di BigQuery con librerie client. Per ulteriori informazioni, consulta API Go BigQuery documentazione di riferimento.

Per eseguire l'autenticazione su BigQuery, configura Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per le librerie client.

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:     "[email protected]",
		}),
	}
	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

Prima di provare questo esempio, segui le istruzioni per la configurazione di Java nel Guida rapida di BigQuery con librerie client. Per ulteriori informazioni, consulta API Java BigQuery documentazione di riferimento.

Per eseguire l'autenticazione su BigQuery, configura Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per le librerie client.

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("[email protected]"), 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

Prima di provare questo esempio, segui le istruzioni per la configurazione di Python nel Guida rapida di BigQuery con librerie client. Per ulteriori informazioni, consulta API Python BigQuery documentazione di riferimento.

Per eseguire l'autenticazione su BigQuery, configura Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per le librerie client.

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 = "[email protected]"
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 "[email protected]" 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}")

Rimuovere l'autorizzazione per una vista

Per rimuovere l'autorizzazione a una vista:

Console

  1. Vai alla pagina BigQuery nella console Google Cloud.

    Vai a BigQuery

  2. Nel riquadro Explorer, espandi il progetto e seleziona un set di dati.

  3. Fai clic su Condivisione &gt; Autorizza visualizzazioni.

  4. Fai clic su Rimuovi autorizzazione.

  5. Fai clic su Chiudi.

Quote e limiti

  • Le viste autorizzate sono soggette a limiti di set di dati. Per ulteriori informazioni, vedi Limiti dei set di dati.
  • Se rimuovi una visualizzazione autorizzata, possono trascorrere fino a 24 ore riferimenti alla vista da rimuovere dal sistema. Per evitare errori, attendere 24 ore prima di riutilizzare il nome di una vista rimossa oppure un nome univoco per la tua vista.

Imporre l'accesso a livello di riga con una visualizzazione

Le viste possono essere utilizzate per limitare l'accesso a colonne (campi) specifici. Se vuoi per limitare l'accesso alle singole righe della tabella, non è necessario creare viste separate per ogni utente o gruppo. In alternativa, puoi utilizzare l'SESSION_USER() per restituire l'indirizzo email dell'utente corrente.

Per mostrare righe diverse a utenti diversi, aggiungi un altro campo alla tabella contenente l'utente autorizzato a visualizzare la riga. Poi, crea una vista che utilizzi la funzione SESSION_USER(). Nell'esempio seguente, i nomi utente sono archiviata nel campo allowed_viewer:

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

Il limite di questo approccio è che puoi concedere l'accesso a un solo un utente alla volta. Puoi ovviare a questo limite rendendo allowed_viewer un campo ripetuto. Questo approccio ti consente di fornire un elenco di utenti per ogni riga. Ma anche se utilizzi un campo ripetuto, l'archiviazione dei nomi utente nella tabella richiede di monitorare manualmente i singoli utenti che hanno accesso a ogni riga di comando.

Compila invece il campo allowed_viewer con i nomi dei gruppi e crea un una tabella separata che mappa i gruppi agli utenti. La tabella che mappa i gruppi agli utenti avrà uno schema che archivia i nomi e i nomi utente dei gruppi. Ad esempio: {group:string, user_name:string}. Questo approccio ti consente di gestire e raggruppa le informazioni separatamente dalla tabella che li contiene.

Se la tabella di mappatura è denominata private.access_control, la query SQL utilizzata per creare la vista autorizzata potrebbe essere:

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

Passaggi successivi