Pular para o conteúdo principal

O que é incorporação para usuários externos?

info

Visualização

Este recurso está em Pré-visualização Pública.

Esta página descreve como funciona a incorporação para usuários externos, como configurar seu workspace Databricks para o compartilhamento seguro de painéis incorporados e como usar aplicativos de exemplo para começar. A incorporação para usuários externos utiliza uma entidade de serviço e access tokens com escopo definido para autenticar e autorizar o acesso aos painéis incorporados. Essa abordagem permite compartilhar dashboards com visualizadores externos à sua organização, como parceiros e clientes, sem a necessidade de provisionar uma conta Databricks para esses usuários.

Para saber mais sobre outras opções de incorporação, incluindo a incorporação de painéis para usuários dentro da sua organização, consulte Incorporar um painel.

Como funciona a incorporação para usuários externos

O diagrama e os passos numerados a seguir explicam como os usuários são autenticados e os painéis são preenchidos com resultados específicos para cada usuário quando você incorpora um painel para usuários externos.

Um fluxograma mostrando as trocas de tokens necessárias entre sua aplicação e o workspace Databricks .

  1. Autenticação e solicitação do usuário: O usuário faz login no seu aplicativo. O frontend da sua aplicação envia uma solicitação autenticada ao seu servidor para obter um access token ao painel de controle.
  2. Autenticação de entidade de serviço: seu servidor usa o segredo de entidade de serviço para solicitar e receber tokens OAuth do servidor Databricks . Trata-se de um token de amplo escopo que pode acessar todas APIs do painel de controle às quais Databricks tem acesso em nome da entidade de serviço. Seu servidor chama o endpoint /tokeninfo usando esses tokens, passando informações básicas do usuário, como external_viewer_id e external_value. Consulte Apresentar painéis de controle de forma segura para usuários individuais.
  3. Geração de tokens com escopo de usuário: Usando a resposta do endpoint /tokeninfo e do endpoint OpenID Connect (OIDC) do Databricks , seu servidor gera novos tokens com escopo restrito que codificam as informações do usuário que você passou.
  4. Renderização do painel e filtragem de dados: A página do aplicativo instancia DatabricksDashboard a partir de @databricks/aibi-client e passa os tokens de escopo do usuário durante a construção. O painel de controle é renderizado de acordo com o contexto do usuário. Este token autoriza o acesso, suporta auditoria com external_viewer_id e carrega external_value para filtragem de dados. As consultas no conjunto de dados do painel podem referenciar __aibi_external_value para aplicar filtros por usuário, garantindo que cada visualizador veja apenas os dados que ele tem permissão para view.

O Ask Genie não está disponível em incorporação externa.

O botão "Pergunte Genie não é compatível com incorporação para usuários externos. Se você deseja fornecer recursos de consulta de dados em linguagem natural para usuários externos, use a API Genie Conversation . A API de Conversas permite que você integre a funcionalidade do Genie ao seu aplicativo programaticamente, independentemente da incorporação do painel.

Para dashboards com incorporação básica, o Ask Genie está disponível. Consulte o Ask Genie nos painéis incorporados.

Apresente dashboards de forma segura para usuários individuais.

Configure seu servidor de aplicativos para gerar tokens exclusivos com escopo de usuário para cada usuário com base em seu external_viewer_id. Isso permite rastrear a visualização do painel e o uso por meio logs de auditoria. O external_viewer_id é emparelhado com um external_value, que atua como uma variável global que pode ser inserida em consultas SQL usadas no conjunto de dados do painel. Isso permite filtrar os dados exibidos no painel para cada usuário.

external_viewer_id é enviado para logs de auditoria do seu painel de controle e não deve incluir informações de identificação pessoal. Esse valor também deve ser único para cada usuário.

external_value É utilizado no processamento de consultas e pode incluir informações de identificação pessoal.

O exemplo a seguir demonstra como usar o valor externo como filtro em consultas dataset :

SQL
SELECT *
FROM sales
WHERE region = __aibi_external_value

Visão geral da configuração

Esta seção inclui uma visão geral conceitual de alto nível dos passos que você precisa executar para configurar a incorporação de um painel em um local externo.

Para incorporar um painel de controle em um aplicativo externo, primeiro você cria uma entidade de serviço no Databricks e gera um segredo. A entidade de serviço deve ter acesso de leitura ao painel de controle e aos dados subjacentes. Seu servidor usa o segredo da entidade de serviço para recuperar tokens que podem acessar APIs do painel em nome da entidade de serviço. Com esses tokens, o servidor chama o endpoint API /tokeninfo , um endpoint OpenID Connect (OIDC) que retorna informações básicas do perfil do usuário, incluindo os valores external_value e external_viewer_id . Esses valores permitem associar solicitações a usuários individuais.

Utilizando os tokens obtidos da entidade de serviço, seu servidor gera novos tokens específicos para o usuário que está acessando o painel de controle. Esses tokens de escopo de usuário são passados para a página do aplicativo, onde o aplicativo instancia o objeto DatabricksDashboard da biblioteca @databricks/aibi-client . Os tokens contêm informações específicas do usuário que permitem a auditoria e aplicam filtros, de forma que cada usuário veja apenas os dados aos quais está autorizado a acessar. Do ponto de vista do usuário, fazer login no aplicativo fornece acesso automático ao painel integrado com a visibilidade correta dos dados.

Limites de taxa e considerações de desempenho

A incorporação externa tem um limite de 20 carregamentos de painel por segundo. Você pode abrir mais de 20 painéis ao mesmo tempo, mas não mais do que 20 podem começar a carregar simultaneamente.

Pré-requisitos

Para implementar a incorporação externa, certifique-se de atender aos seguintes pré-requisitos:

  • Você precisa ter, no mínimo, permissões CAN MANAGE em um painel publicado. Consulte o tutorial: Use dashboards de exemplo para criar e publicar rapidamente um dashboard de exemplo, se necessário.
  • Você precisa ter Databricks CLI versão 0.205 ou superior instalado. Consulte a seção Instalar ou atualizar a CLI do Databricks para obter instruções. Para configurar e usar a autenticação OAuth, consulte Autenticação OAuth de usuário para máquina (U2M).
  • O administrador workspace deve definir uma lista de domínios aprovados que podem hospedar o painel de controle incorporado. Consulte a seção "Gerenciar incorporação de painel" para obter instruções.
  • Um aplicativo externo para hospedar seu painel de controle incorporado. Você pode usar seu próprio aplicativo ou usar os aplicativos de exemplo fornecidos.

o passo 1: Criar uma entidade de serviço

Crie uma entidade de serviço para servir como identidade da sua aplicação externa no Databricks. Esta entidade de serviço autentica solicitações em nome do seu aplicativo.

Para criar uma entidade de serviço:

  1. Como administrador do workspace, faça login no workspace do Databricks.
  2. Clique no seu nome de usuário na barra superior do workspace do Databricks e selecione Configurações .
  3. Clique em Identidade e acesso no painel esquerdo.
  4. Ao lado de Entidades de serviço , clique em Gerenciar .
  5. Clique em Adicionar entidade de serviço .
  6. Clique em Adicionar novo .
  7. Insira um nome descritivo para a entidade de serviço.
  8. Clique em Adicionar .
  9. Abra a entidade de serviço que você acabou de criar na página de listagem de entidades de serviço . Use o campo de filtro para pesquisar pelo nome, se necessário.
  10. Na página de detalhes da entidade de serviço , registre o ID do aplicativo . Verifique se as caixas de seleção " AcessoDatabricks SQL e " Acesso ao espaço de trabalho" estão marcadas.

o passo 2: Criar um segredo OAuth

Gere um segredo para a entidade de serviço e colete os seguintes valores de configuração, que você precisará para seu aplicativo externo:

  • ID da entidade de serviço (cliente)
  • Segredo do cliente

A entidade de serviço utiliza um segredo OAuth para verificar sua identidade ao solicitar um access token do seu aplicativo externo.

Para gerar um segredo:

  1. Clique em Segredos na página de detalhes da entidade de serviço .
  2. Clique em Gerar segredo .
  3. Insira o valor da duração da vida para o novo segredo em dias (por exemplo, entre 1 e 730 dias).
  4. Copie o segredo imediatamente. Você não poderá view este segredo novamente depois de sair desta tela.

o passo 3: Atribua permissões à sua entidade de serviço

A entidade de serviço que você criou funciona como a identidade que fornece acesso ao painel de controle por meio do seu aplicativo. Suas permissões se aplicam somente se o painel não for publicado com permissões de dados compartilhados. Se forem utilizadas permissões de dados compartilhados, as credenciais do editor acessarão os dados. Para obter mais detalhes e recomendações, consulte Incorporando abordagens de autenticação.

  1. Clique em Painéis na barra lateral workspace para abrir a página com a lista de painéis.
  2. Clique no nome do painel que deseja incorporar. O painel de controle publicado é aberto.
  3. Clique em Compartilhar .
  4. Utilize o campo de entrada de texto na caixa de diálogo de compartilhamento para encontrar sua entidade de serviço e, em seguida, clique nela. Defina o nível de permissão para CAN RUN . Em seguida, clique em Adicionar .
  5. Anote o ID do painel de controle . Você pode encontrar o ID do painel no URL do painel (por exemplo, https://<your-workspace-url>/dashboards/<dashboard-id>). Veja os detalhes workspace Databricks.
nota

Se você publicar um painel com permissões de dados individuais, deverá conceder à sua entidade de serviço acesso aos dados usados no painel. O acesso computacional sempre utiliza as credenciais do editor, portanto, você não precisa conceder permissões compute à entidade de serviço.

Para ler e exibir dados, a entidade de serviço deve ter pelo menos SELECT privilégios nas tabelas e visualizações referenciadas no painel. Veja Quem pode gerenciar privilégios?

Etapa 4: Use o aplicativo de exemplo para autenticar e gerar tokens

Utilize um aplicativo de exemplo para praticar a incorporação externa do seu painel de controle. Os aplicativos incluem instruções e código que iniciam a troca de tokens necessária para gerar tokens com escopo definido. Os seguintes blocos de código não possuem dependências. Copie e salve um dos seguintes aplicativos.

Copie e salve isto em um arquivo chamado example.py.

Python
#!/usr/bin/env python3

import os
import sys
import json
import base64
import urllib.request
import urllib.parse
from http.server import HTTPServer, BaseHTTPRequestHandler

# -----------------------------------------------------------------------------
# Config
# -----------------------------------------------------------------------------
CONFIG = {
"instance_url": os.environ.get("INSTANCE_URL"),
"dashboard_id": os.environ.get("DASHBOARD_ID"),
"service_principal_id": os.environ.get("SERVICE_PRINCIPAL_ID"),
"service_principal_secret": os.environ.get("SERVICE_PRINCIPAL_SECRET"),
"external_viewer_id": os.environ.get("EXTERNAL_VIEWER_ID"),
"external_value": os.environ.get("EXTERNAL_VALUE"),
"workspace_id": os.environ.get("WORKSPACE_ID"),
"port": int(os.environ.get("PORT", 3000)),
}

basic_auth = base64.b64encode(
f"{CONFIG['service_principal_id']}:{CONFIG['service_principal_secret']}".encode()
).decode()

# -----------------------------------------------------------------------------
# HTTP Request Helper
# -----------------------------------------------------------------------------
def http_request(url, method="GET", headers=None, body=None):
headers = headers or {}
if body is not None and not isinstance(body, (bytes, str)):
raise ValueError("Body must be bytes or str")

req = urllib.request.Request(url, method=method, headers=headers)
if body is not None:
if isinstance(body, str):
body = body.encode()
req.data = body

try:
with urllib.request.urlopen(req) as resp:
data = resp.read().decode()
try:
return {"data": json.loads(data)}
except json.JSONDecodeError:
return {"data": data}
except urllib.error.HTTPError as e:
raise RuntimeError(f"HTTP {e.code}: {e.read().decode()}") from None

# -----------------------------------------------------------------------------
# Token logic
# -----------------------------------------------------------------------------
def get_scoped_token():
# 1. Get all-api token
oidc_res = http_request(
f"{CONFIG['instance_url']}/oidc/v1/token",
method="POST",
headers={
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": f"Basic {basic_auth}",
},
body=urllib.parse.urlencode({
"grant_type": "client_credentials",
"scope": "all-apis"
})
)
oidc_token = oidc_res["data"]["access_token"]

# 2. Get token info
token_info_url = (
f"{CONFIG['instance_url']}/api/2.0/lakeview/dashboards/"
f"{CONFIG['dashboard_id']}/published/tokeninfo"
f"?external_viewer_id={urllib.parse.quote(CONFIG['external_viewer_id'])}"
f"&external_value={urllib.parse.quote(CONFIG['external_value'])}"
)
token_info = http_request(
token_info_url,
headers={"Authorization": f"Bearer {oidc_token}"}
)["data"]

# 3. Generate scoped token
params = token_info.copy()
authorization_details = params.pop("authorization_details", None)
params.update({
"grant_type": "client_credentials",
"authorization_details": json.dumps(authorization_details)
})

scoped_res = http_request(
f"{CONFIG['instance_url']}/oidc/v1/token",
method="POST",
headers={
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": f"Basic {basic_auth}",
},
body=urllib.parse.urlencode(params)
)
return scoped_res["data"]["access_token"]

# -----------------------------------------------------------------------------
# HTML generator
# -----------------------------------------------------------------------------
def generate_html(token):
return f"""<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dashboard Demo</title>
<style>
body {{ font-family: system-ui; margin: 0; padding: 20px; background: #f5f5f5; }}
.container {{ max-width: 1200px; margin: 0 auto; height:calc(100vh - 40px) }}
</style>
</head>
<body>
<div id="dashboard-content" class="container"></div>
<script type="module">
import {{ DatabricksDashboard }} from "https://cdn.jsdelivr.net/npm/@databricks/aibi-client@0.0.0-alpha.7/+esm";
const dashboard = new DatabricksDashboard({{
instanceUrl: "{CONFIG['instance_url']}",
workspaceId: "{CONFIG['workspace_id']}",
dashboardId: "{CONFIG['dashboard_id']}",
token: "{token}",
container: document.getElementById("dashboard-content")
}});
dashboard.initialize();
</script>
</body>
</html>"""

# -----------------------------------------------------------------------------
# HTTP server
# -----------------------------------------------------------------------------
class RequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
if self.path != "/":
self.send_response(404)
self.send_header("Content-Type", "text/plain")
self.end_headers()
self.wfile.write(b"Not Found")
return

try:
token = get_scoped_token()
html = generate_html(token)
status = 200
except Exception as e:
html = f"<h1>Error</h1><p>{e}</p>"
status = 500

self.send_response(status)
self.send_header("Content-Type", "text/html")
self.end_headers()
self.wfile.write(html.encode())

def start_server():
missing = [k for k, v in CONFIG.items() if not v]
if missing:
print(f"Missing: {', '.join(missing)}", file=sys.stderr)
sys.exit(1)

server = HTTPServer(("localhost", CONFIG["port"]), RequestHandler)
print(f":rocket: Server running on http://localhost:{CONFIG['port']}")
try:
server.serve_forever()
except KeyboardInterrupt:
sys.exit(0)

if __name__ == "__main__":
start_server()

o passo 5: execução da aplicação exemplo

Substitua os seguintes valores e, em seguida, execute o bloco de código a partir do seu terminal. Seus valores não devem estar entre colchetes angulares (< >):

  • Utilize o URLworkspace para localizar e substituir os seguintes valores:

    • <your-instance>
    • <workspace_id>
    • <dashboard_id>
  • Substitua os seguintes valores pelos valores que você criou ao criar a entidade de serviço (o passo 2):

    • <service_principal_id>
    • <service_principal_secret> (segredo do cliente)
  • Substitua os seguintes valores pelos identificadores associados aos usuários do aplicativo externo:

    • <some-external-viewer>
    • <some-external-value>
  • Substitua </path/to/example> pelo caminho para o arquivo .py ou .js que você criou na etapa anterior. Inclua a extensão do arquivo.

nota

Não inclua nenhuma informação de identificação pessoal (PII) no valor EXTERNAL_VIEWER_ID .

Bash

INSTANCE_URL='https://<your-instance>.databricks.com' \
WORKSPACE_ID='<workspace_id>' \
DASHBOARD_ID='<dashboard_id>' \
SERVICE_PRINCIPAL_ID='<service-principal-id>' \
SERVICE_PRINCIPAL_SECRET='<service-principal_secret>' \
EXTERNAL_VIEWER_ID='<some-external-viewer>' \
EXTERNAL_VALUE='<some-external-value>' \
~</path/to/example>

# Terminal will output: :rocket: Server running on http://localhost:3000