配置 Superset
superset_config.py
Superset 通过其 config.py 模块 公开数百个可配置参数。公开的变量和对象充当您可能想要配置、修改和交互的大部分内容的公共接口。在此 python 模块中,您将找到所有这些参数、合理的默认值,以及以注释形式提供的丰富文档
要配置您的应用程序,您需要创建自己的配置模块,这将允许您覆盖这些参数中的部分或全部。您无需更改核心模块,而应定义自己的模块(通常是一个名为 superset_config.py
的文件)。将此文件添加到您的 PYTHONPATH
或创建一个环境变量 SUPERSET_CONFIG_PATH
指定 superset_config.py
的完整路径。
例如,如果直接在您的 superset_config.py
位于 /app
目录下的基于 Linux 的系统上部署 Superset,您可以运行
export SUPERSET_CONFIG_PATH=/app/superset_config.py
如果您使用自己的自定义 Dockerfile,以官方 Superset 镜像作为基础镜像,那么您可以添加如下所示的覆盖
COPY --chown=superset superset_config.py /app/
ENV SUPERSET_CONFIG_PATH /app/superset_config.py
Docker compose 部署使用特定约定以不同的方式处理应用程序配置。有关详细信息,请参阅 docker compose 技巧与配置。
以下是在您的 superset_config.py
文件中可以设置的一些参数的示例
# Superset specific config
ROW_LIMIT = 5000
# Flask App Builder configuration
# Your App secret key will be used for securely signing the session cookie
# and encrypting sensitive information on the database
# Make sure you are changing this key for your deployment with a strong key.
# Alternatively you can set it with `SUPERSET_SECRET_KEY` environment variable.
# You MUST set this for production environments or the server will refuse
# to start and you will see an error in the logs accordingly.
SECRET_KEY = 'YOUR_OWN_RANDOM_GENERATED_SECRET_KEY'
# The SQLAlchemy connection string to your database backend
# This connection defines the path to the database that stores your
# superset metadata (slices, connections, tables, dashboards, ...).
# Note that the connection information to connect to the datasources
# you want to explore are managed directly in the web UI
# The check_same_thread=false property ensures the sqlite client does not attempt
# to enforce single-threaded access, which may be problematic in some edge cases
SQLALCHEMY_DATABASE_URI = 'sqlite:////path/to/superset.db?check_same_thread=false'
# Flask-WTF flag for CSRF
WTF_CSRF_ENABLED = True
# Add endpoints that need to be exempt from CSRF protection
WTF_CSRF_EXEMPT_LIST = []
# A CSRF token that expires in 1 year
WTF_CSRF_TIME_LIMIT = 60 * 60 * 24 * 365
# Set this API key to enable Mapbox visualizations
MAPBOX_API_KEY = ''
请注意,通常情况下,您只需要将核心 superset/config.py 中要更改的部分(以及相关注释)复制粘贴到您的 superset_config.py
文件中。
您可以在本地 superset_config.py
中更改 superset/config.py 中定义的所有参数和默认值。管理员将需要阅读此文件,以了解可以在本地配置的内容以及当前使用的默认值。
由于 superset_config.py
充当 Flask 配置模块,因此它可用于更改 Flask 本身的设置,以及 Superset 捆绑的 Flask 扩展(如 flask-wtf
、flask-caching
、flask-migrate
和 flask-appbuilder
)。这些扩展中的每一个都提供复杂的配置功能。Flask App Builder 是 Superset 使用的 Web 框架,它也提供许多配置设置。有关如何配置它的更多信息,请参阅 Flask App Builder 文档。
至少,您需要更改 SECRET_KEY
和 SQLALCHEMY_DATABASE_URI
。继续阅读以了解更多有关每个设置的信息。
指定 SECRET_KEY
添加初始 SECRET_KEY
Superset 需要用户指定的 SECRET_KEY 才能启动。此要求是 在版本 2.1.0 中添加的,以强制执行安全配置。将一个强 SECRET_KEY 添加到您的 superset_config.py
文件中,如下所示
SECRET_KEY = 'YOUR_OWN_RANDOM_GENERATED_SECRET_KEY'
您可以使用 openssl rand -base64 42
生成一个强安全密钥。
此密钥将用于安全地签署会话 Cookie 并加密存储在 Superset 应用程序元数据数据库中的敏感信息。您的部署必须使用一个复杂、唯一的密钥。
旋转到一个新的 SECRET_KEY
如果您希望更改现有的 SECRET_KEY,请将现有的 SECRET_KEY 添加到您的 superset_config.py
文件中,作为 PREVIOUS_SECRET_KEY =
,并将您的新密钥提供为 SECRET_KEY =
。您可以使用以下命令找到当前的 SECRET_KEY - 如果使用 Docker 运行 Superset,请从 Superset 应用程序容器中执行
superset shell
from flask import current_app; print(current_app.config["SECRET_KEY"])
保存包含这些值的 superset_config.py
,然后运行 superset re-encrypt-secrets
。
设置生产元数据数据库
Superset 需要一个数据库来存储它管理的信息,例如图表、仪表板的定义以及许多其他内容。
默认情况下,Superset 被配置为使用 SQLite,这是一个独立的单文件数据库,它提供了一种简单快捷的入门方式(无需任何安装)。但是,对于生产环境,由于安全、可扩展性和数据完整性原因,强烈建议不要使用 SQLite。务必仅使用支持的数据库引擎,并考虑在单独的主机或容器上使用不同的数据库引擎。
Superset 支持以下数据库引擎/版本
数据库引擎 | 支持的版本 |
---|---|
PostgreSQL | 10.X、11.X、12.X、13.X、14.X、15.X |
MySQL | 5.7、8.X |
使用以下数据库驱动程序和连接字符串
数据库 | PyPI 包 | 连接字符串 |
---|---|---|
PostgreSQL | pip install psycopg2 | postgresql://<UserName>:<DBPassword>@<Database Host>/<Database Name> |
MySQL | pip install mysqlclient | mysql://<UserName>:<DBPassword>@<Database Host>/<Database Name> |
正确设置元数据存储超出了本文档的范围。我们建议使用托管管理服务(例如 Amazon RDS 或 Google Cloud Databases)来处理服务和支持的基础设施以及备份策略。
要配置 Superset 元数据存储,请在 superset_config
上将 SQLALCHEMY_DATABASE_URI
配置键设置为相应的连接字符串。
在 WSGI HTTP 服务器上运行
虽然您可以在 NGINX 或 Apache 上运行 Superset,但我们建议在异步模式下使用 Gunicorn。这即使在高并发的情况下也能实现出色的并发性,并且安装和配置相当容易。请参阅您首选技术的相关文档,以在您的环境中以有效的方式设置此 Flask WSGI 应用程序。以下是已知在生产环境中运行良好的异步设置
-w 10 \
-k gevent \
--worker-connections 1000 \
--timeout 120 \
-b 0.0.0.0:6666 \
--limit-request-line 0 \
--limit-request-field_size 0 \
--statsd-host localhost:8125 \
"superset.app:create_app()"
有关更多信息,请参阅 Gunicorn 文档。请注意,开发 Web 服务器(superset run
或 flask run
)不适用于生产环境。
如果您不使用 Gunicorn,则可能需要通过在 superset_config.py
中设置 COMPRESS_REGISTER = False
来禁用使用 flask-compress
。
目前,Google BigQuery Python SDK 与 gevent
不兼容,这是由于 gevent
对 Python 核心库进行了一些动态猴子补丁。因此,当您在 Superset 上使用 BigQuery
数据源时,您必须使用 gunicorn
工作程序类型(除了 gevent
之外)。
HTTPS 配置
您可以通过负载均衡器或反向代理(如 nginx)配置 HTTPS 上游,并在流量到达 Superset 应用程序之前执行 SSL/TLS 卸载。在此设置中,来自执行警报与报表图表快照的 Celery 工作程序的本地流量可以从入口点后面以 http://
URL 访问 Superset。如果您使用的是官方 Superset Docker 镜像,还可以配置 Gunicorn(Python Web 服务器)中的 SSL。
负载均衡器背后的配置
如果您在负载均衡器或反向代理(例如 AWS 上的 NGINX 或 ELB)后面运行 superset,您可能需要使用健康检查端点,以便您的负载均衡器知道您的 superset 实例是否正在运行。这在 /health
上提供,如果 Web 服务器正在运行,它将返回包含“OK”的 200 响应。
如果负载均衡器正在插入 X-Forwarded-For/X-Forwarded-Proto
标头,您应该在 superset 配置文件(superset_config.py
)中设置 ENABLE_PROXY_FIX = True
,以提取和使用这些标头。
如果反向代理用于提供 SSL 加密,则可能需要明确定义 X-Forwarded-Proto
。对于 Apache Web 服务器,可以按如下方式设置
RequestHeader set X-Forwarded-Proto "https"
自定义 OAuth2 配置
Superset 基于 Flask-AppBuilder (FAB),它开箱即用地支持许多提供商(GitHub、Twitter、LinkedIn、Google、Azure 等)。除此之外,Superset 可以配置为连接到支持“code”授权的其他 OAuth2 授权服务器实现。
确保在 Web 服务器上安装了 pip 包 Authlib
。
首先,在 Superset superset_config.py
中配置授权。
from flask_appbuilder.security.manager import AUTH_OAUTH
# Set the authentication type to OAuth
AUTH_TYPE = AUTH_OAUTH
OAUTH_PROVIDERS = [
{ 'name':'egaSSO',
'token_key':'access_token', # Name of the token in the response of access_token_url
'icon':'fa-address-card', # Icon for the provider
'remote_app': {
'client_id':'myClientId', # Client Id (Identify Superset application)
'client_secret':'MySecret', # Secret for this Client Id (Identify Superset application)
'client_kwargs':{
'scope': 'read' # Scope for the Authorization
},
'access_token_method':'POST', # HTTP Method to call access_token_url
'access_token_params':{ # Additional parameters for calls to access_token_url
'client_id':'myClientId'
},
'jwks_uri':'https://myAuthorizationServe/adfs/discovery/keys', # may be required to generate token
'access_token_headers':{ # Additional headers for calls to access_token_url
'Authorization': 'Basic Base64EncodedClientIdAndSecret'
},
'api_base_url':'https://myAuthorizationServer/oauth2AuthorizationServer/',
'access_token_url':'https://myAuthorizationServer/oauth2AuthorizationServer/token',
'authorize_url':'https://myAuthorizationServer/oauth2AuthorizationServer/authorize'
}
}
]
# Will allow user self registration, allowing to create Flask users from Authorized User
AUTH_USER_REGISTRATION = True
# The default user self registration role
AUTH_USER_REGISTRATION_ROLE = "Public"
然后,创建一个扩展 SupersetSecurityManager
并覆盖 oauth_user_info
的 CustomSsoSecurityManager
import logging
from superset.security import SupersetSecurityManager
class CustomSsoSecurityManager(SupersetSecurityManager):
def oauth_user_info(self, provider, response=None):
logging.debug("Oauth2 provider: {0}.".format(provider))
if provider == 'egaSSO':
# As example, this line request a GET to base_url + '/' + userDetails with Bearer Authentication,
# and expects that authorization server checks the token, and response with user details
me = self.appbuilder.sm.oauth_remotes[provider].get('userDetails').data
logging.debug("user_data: {0}".format(me))
return { 'name' : me['name'], 'email' : me['email'], 'id' : me['user_name'], 'username' : me['user_name'], 'first_name':'', 'last_name':''}
...
此文件必须与 superset_config.py
位于同一目录中,名称为 custom_sso_security_manager.py
。最后,将以下 2 行添加到 superset_config.py
中
from custom_sso_security_manager import CustomSsoSecurityManager
CUSTOM_SECURITY_MANAGER = CustomSsoSecurityManager
备注
-
重定向 URL 将为
https://<superset-webserver>/oauth-authorized/<provider-name>
。如果需要,在配置 OAuth2 授权提供商时。例如,对于上述配置,重定向 URL 将为https://<superset-webserver>/oauth-authorized/egaSSO
。 -
如果 OAuth2 授权服务器支持 OpenID Connect 1.0,则可以仅配置其配置文档 URL,而不提供
api_base_url
、access_token_url
、authorize_url
和其他必需的选项(如用户信息端点、jwks uri 等)。例如OAUTH_PROVIDERS = [
{ 'name':'egaSSO',
'token_key':'access_token', # Name of the token in the response of access_token_url
'icon':'fa-address-card', # Icon for the provider
'remote_app': {
'client_id':'myClientId', # Client Id (Identify Superset application)
'client_secret':'MySecret', # Secret for this Client Id (Identify Superset application)
'server_metadata_url': 'https://myAuthorizationServer/.well-known/openid-configuration'
}
}
]
使用 Flask-OIDC 的 Keycloak 特定配置
如果您使用 Keycloak 作为 OpenID Connect 1.0 提供商,则上述基于 Authlib
的配置可能无法正常工作。在这种情况下,使用 Flask-OIDC
是一个可行的选择。
确保在 Web 服务器上安装了 pip 包 Flask-OIDC
。已成功测试使用版本 2.2.0。此包需要 Flask-OpenID
作为依赖项。
以下代码定义了一个新的安全管理器。将其添加到名为 keycloak_security_manager.py
的新文件中,并将其放置在与您的 superset_config.py
文件相同的目录中。
from flask_appbuilder.security.manager import AUTH_OID
from superset.security import SupersetSecurityManager
from flask_oidc import OpenIDConnect
from flask_appbuilder.security.views import AuthOIDView
from flask_login import login_user
from urllib.parse import quote
from flask_appbuilder.views import ModelView, SimpleFormView, expose
from flask import (
redirect,
request
)
import logging
class OIDCSecurityManager(SupersetSecurityManager):
def __init__(self, appbuilder):
super(OIDCSecurityManager, self).__init__(appbuilder)
if self.auth_type == AUTH_OID:
self.oid = OpenIDConnect(self.appbuilder.get_app)
self.authoidview = AuthOIDCView
class AuthOIDCView(AuthOIDView):
@expose('/login/', methods=['GET', 'POST'])
def login(self, flag=True):
sm = self.appbuilder.sm
oidc = sm.oid
@self.appbuilder.sm.oid.require_login
def handle_login():
user = sm.auth_user_oid(oidc.user_getfield('email'))
if user is None:
info = oidc.user_getinfo(['preferred_username', 'given_name', 'family_name', 'email'])
user = sm.add_user(info.get('preferred_username'), info.get('given_name'), info.get('family_name'),
info.get('email'), sm.find_role('Gamma'))
login_user(user, remember=False)
return redirect(self.appbuilder.get_url_for_index)
return handle_login()
@expose('/logout/', methods=['GET', 'POST'])
def logout(self):
oidc = self.appbuilder.sm.oid
oidc.logout()
super(AuthOIDCView, self).logout()
redirect_url = request.url_root.strip('/') + self.appbuilder.get_url_for_login
return redirect(
oidc.client_secrets.get('issuer') + '/protocol/openid-connect/logout?redirect_uri=' + quote(redirect_url))
然后将其添加到您的 superset_config.py
文件中
from keycloak_security_manager import OIDCSecurityManager
from flask_appbuilder.security.manager import AUTH_OID, AUTH_REMOTE_USER, AUTH_DB, AUTH_LDAP, AUTH_OAUTH
import os
AUTH_TYPE = AUTH_OID
SECRET_KEY: 'SomethingNotEntirelySecret'
OIDC_CLIENT_SECRETS = '/path/to/client_secret.json'
OIDC_ID_TOKEN_COOKIE_SECURE = False
OIDC_OPENID_REALM: '<myRealm>'
OIDC_INTROSPECTION_AUTH_METHOD: 'client_secret_post'
CUSTOM_SECURITY_MANAGER = OIDCSecurityManager
# Will allow user self registration, allowing to create Flask users from Authorized User
AUTH_USER_REGISTRATION = True
# The default user self registration role
AUTH_USER_REGISTRATION_ROLE = 'Public'
将您的客户端特定 OpenID 信息存储在一个名为 client_secret.json
的文件中。在与 superset_config.py
相同的目录中创建此文件
{
"<myOpenIDProvider>": {
"issuer": "https://<myKeycloakDomain>/realms/<myRealm>",
"auth_uri": "https://<myKeycloakDomain>/realms/<myRealm>/protocol/openid-connect/auth",
"client_id": "https://<myKeycloakDomain>",
"client_secret": "<myClientSecret>",
"redirect_uris": [
"https://<SupersetWebserver>/oauth-authorized/<myOpenIDProvider>"
],
"userinfo_uri": "https://<myKeycloakDomain>/realms/<myRealm>/protocol/openid-connect/userinfo",
"token_uri": "https://<myKeycloakDomain>/realms/<myRealm>/protocol/openid-connect/token",
"token_introspection_uri": "https://<myKeycloakDomain>/realms/<myRealm>/protocol/openid-connect/token/introspect"
}
}
LDAP 身份验证
FAB 支持针对 LDAP 服务器验证用户凭据。要使用 LDAP,您必须安装 python-ldap 包。有关详细信息,请参阅 FAB 的 LDAP 文档。
将 LDAP 或 OAUTH 组映射到 Superset 角色
Flask-AppBuilder 中的 AUTH_ROLES_MAPPING
是一个字典,用于将 LDAP/OAUTH 组名映射到 FAB 角色。它用于将角色分配给使用 LDAP 或 OAuth 进行身份验证的用户。
将 OAUTH 组映射到 Superset 角色
以下 AUTH_ROLES_MAPPING
字典会将 OAUTH 组“superset_users”映射到 Superset 角色“Gamma”和“Alpha”,并将 OAUTH 组“superset_admins”映射到 Superset 角色“Admin”。
AUTH_ROLES_MAPPING = {
"superset_users": ["Gamma","Alpha"],
"superset_admins": ["Admin"],
}
将 LDAP 组映射到 Superset 角色
以下 AUTH_ROLES_MAPPING
字典会将 LDAP DN“cn=superset_users,ou=groups,dc=example,dc=com”映射到 Superset 角色“Gamma”和“Alpha”,并将 LDAP DN“cn=superset_admins,ou=groups,dc=example,dc=com”映射到 Superset 角色“Admin”。
AUTH_ROLES_MAPPING = {
"cn=superset_users,ou=groups,dc=example,dc=com": ["Gamma","Alpha"],
"cn=superset_admins,ou=groups,dc=example,dc=com": ["Admin"],
}
注意:这需要设置 AUTH_LDAP_SEARCH
。有关更多详细信息,请参阅 FAB 安全文档。
在登录时同步角色
您还可以使用 AUTH_ROLES_SYNC_AT_LOGIN
配置变量来控制 Flask-AppBuilder 多久同步一次用户的角色与 LDAP/OAUTH 组。如果 AUTH_ROLES_SYNC_AT_LOGIN
设置为 True,Flask-AppBuilder 将在用户每次登录时同步用户的角色。如果 AUTH_ROLES_SYNC_AT_LOGIN
设置为 False,Flask-AppBuilder 仅在用户首次注册时同步用户的角色。
Flask 应用程序配置钩子
FLASK_APP_MUTATOR
是一个可以在你的环境中提供的配置函数,它接收应用程序对象并可以以任何方式更改它。例如,将 FLASK_APP_MUTATOR
添加到你的 superset_config.py
中,以将会话 Cookie 的过期时间设置为 24 小时。
from flask import session
from flask import Flask
def make_session_permanent():
'''
Enable maxAge for the cookie 'session'
'''
session.permanent = True
# Set up max age of session to 24 hours
PERMANENT_SESSION_LIFETIME = timedelta(hours=24)
def FLASK_APP_MUTATOR(app: Flask) -> None:
app.before_request_funcs.setdefault(None, []).append(make_session_permanent)
功能标记
为了支持各种用户,Superset 有一些默认情况下未启用的功能。例如,一些用户有更严格的安全限制,而另一些用户可能没有。因此,Superset 允许用户通过配置启用或禁用某些功能。对于功能所有者,你可以在 Superset 中添加可选功能,但这些功能只会影响部分用户。
你可以使用 superset_config.py
中的标志启用或禁用功能。
FEATURE_FLAGS = {
'PRESTO_EXPAND_DATA': False,
}
可以在 RESOURCES/FEATURE_FLAGS.md 中找到当前的功能标记列表。