configuring-superset
:::
Using an environment variable for SECRET_KEY
Alternatively, you can set the SECRET_KEY
using an environment variable:
export SUPERSET_SECRET_KEY='YOUR_OWN_RANDOM_GENERATED_SECRET_KEY'
This is useful for deployments where you want to avoid hardcoding sensitive information in your configuration files.
Configuring the SQLAlchemy Database URI
The SQLALCHEMY_DATABASE_URI
is the connection string to your database backend. This connection defines the path to the database that stores your Superset metadata (slices, connections, tables, dashboards, etc.). The connection information to connect to the datasources you want to explore are managed directly in the web UI.
SQLite
If you are using SQLite, you can set the SQLALCHEMY_DATABASE_URI
like this:
SQLALCHEMY_DATABASE_URI = 'sqlite:////path/to/superset.db?check_same_thread=false'
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.
PostgreSQL
If you are using PostgreSQL, you can set the SQLALCHEMY_DATABASE_URI
like this:
SQLALCHEMY_DATABASE_URI = 'postgresql+psycopg2://superset:superset@localhost:5432/superset'
MySQL
If you are using MySQL, you can set the SQLALCHEMY_DATABASE_URI
like this:
SQLALCHEMY_DATABASE_URI = 'mysql://superset:superset@localhost:3306/superset'
Other Databases
For other databases, refer to the SQLAlchemy documentation for the appropriate connection string format.
Configuring Flask-WTF
Flask-WTF is used for form handling and CSRF protection in Superset. You can configure it in your superset_config.py
file.
Enabling CSRF Protection
To enable CSRF protection, set the following:
WTF_CSRF_ENABLED = True
Exempting Endpoints from CSRF Protection
To exempt specific endpoints from CSRF protection, add them to the WTF_CSRF_EXEMPT_LIST
:
WTF_CSRF_EXEMPT_LIST = ['/your-endpoint', '/another-endpoint']
Setting CSRF Token Expiry
To set the CSRF token expiry time, use the WTF_CSRF_TIME_LIMIT
parameter:
WTF_CSRF_TIME_LIMIT = 60 * 60 * 24 * 365 # 1 year
Configuring Mapbox
To enable Mapbox visualizations, you need to set your Mapbox API key in your superset_config.py
file:
MAPBOX_API_KEY = 'your-mapbox-api-key'
Configuring Other Flask Extensions
Superset uses several Flask extensions, each of which can be configured in your superset_config.py
file. For example:
Flask-Caching
To configure Flask-Caching, you can set the following:
CACHE_TYPE = 'redis'
CACHE_REDIS_URL = 'redis://localhost:6379/0'
Flask-Migrate
To configure Flask-Migrate, you can set the following:
SQLALCHEMY_MIGRATE_REPO = '/path/to/migrations'
Flask-AppBuilder
To configure Flask-AppBuilder, you can set the following:
FAB_API_MAX_PAGE_SIZE = 100
For more details on configuring these extensions, refer to their respective documentation.
Conclusion
Superset offers a wide range of configuration options through its superset_config.py
file. By understanding and customizing these settings, you can tailor Superset to meet the specific needs of your deployment.
此密钥将用于安全地签署会话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
数据源时,必须使用除gevent
之外的gunicorn
工作类型。
HTTPS配置
您可以通过负载均衡器或反向代理(如nginx)配置HTTPS上游,并在流量到达Superset应用程序之前进行SSL/TLS卸载。在此设置中,从Celery工作节点获取图表快照以用于警报和报告的本地流量可以通过http://
URL访问Superset,从入口点后面访问。
如果您使用的是官方Superset Docker镜像,您还可以在Gunicorn中配置SSL(Python Web服务器)。
在负载均衡器后配置
如果您在负载均衡器或反向代理(例如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
# 将认证类型设置为 OAuth
AUTH_TYPE = AUTH_OAUTH
OAUTH_PROVIDERS = [
{ 'name':'egaSSO',
'token_key':'access_token', # access_token_url 响应中令牌的名称
'icon':'fa-address-card', # 提供者的图标
'remote_app': {
'client_id':'myClientId', # 客户端 ID(标识 Superset 应用程序)
'client_secret':'MySecret', # 此客户端 ID 的密钥(标识 Superset 应用程序)
'client_kwargs':{
'scope': 'read' # 授权的范围
},
'access_token_method':'POST', # 调用 access_token_url 的 HTTP 方法
'access_token_params':{ # 调用 access_token_url 时的额外参数
'client_id':'myClientId'
},
'jwks_uri':'https://myAuthorizationServe/adfs/discovery/keys', # 可能需要生成令牌
'access_token_headers':{ # 调用 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'
}
}
]
# 允许用户自行注册,允许从授权用户创建 Flask 用户
AUTH_USER_REGISTRATION = True
# 默认的用户自行注册角色
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':
# 例如,此行请求一个 GET 到 base_url + '/' + userDetails,使用 Bearer 认证,
# 并期望授权服务器检查令牌,并返回用户详细信息
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
。最后,在 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', # access_token_url 响应中令牌的名称
'icon':'fa-address-card', # 提供者的图标
'remote_app': {
'client_id':'myClientId', # 客户端 ID(标识 Superset 应用程序)
'client_secret':'MySecret', # 此客户端 ID 的密钥(标识 Superset 应用程序)
'client_kwargs':{
'scope': 'read' # 授权的范围
},
'access_token_method':'POST', # 调用 access_token_url 的 HTTP 方法
'access_token_params':{ # 调用 access_token_url 时的额外参数
'client_id':'myClientId'
},
'jwks_uri':'https://myAuthorizationServe/adfs/discovery/keys', # 可能需要生成令牌
'access_token_headers':{ # 调用 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'
}
}
]
```json
[
{
"client_id": "myClientId",
"client_secret": "myClientSecret",
"api_base_url": "https://myAuthorizationServer/oauth2",
"access_token_url": "https://myAuthorizationServer/oauth2/access_token",
"authorize_url": "https://myAuthorizationServer/oauth2/authorize",
"client_kwargs": {
"scope": "openid profile email"
},
"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
# 允许用户自行注册,允许从授权用户创建 Flask 用户
AUTH_USER_REGISTRATION = True
# 默认用户自行注册角色
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():
'''
为 cookie 'session' 启用 maxAge
'''
session.permanent = True
# 将会话的最大年龄设置为 24 小时
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 中找到。