Superset 用户集成方案
注意,一下内容来自外网浏览器翻译,本人使用了将superset集成进入第三方系统,superset采用自定义身份验证+第三系统iframe嵌入方式,但是这个方式存在一个问题,iframe与redirect结合会导致session丢失问题,目前还没有解决,如果你解决了,还请留言说明,感谢分享,目前有价值的资料比较少;
以下原文链接:https://sairamkrish.medium.com/apache-superset-custom-authentication-and-integrate-with-other-micro-services-8217956273c1
坦率地说,超集的文档是很利米资讯科技教育在这方面。从身份验证集成开始,我们需要花费大量时间来弄清楚自己。我搜索了很多,无论我去哪里(谷歌、stackoverflow、superset github 问题、flask appbuilder github 问题),很多人都会问关于自定义身份验证层的问题。希望这篇文章能节省其他人的时间。
自定义身份验证 - 问题陈述
- Superset 是基于flask-appbuilder 的,它也提供了认证层。Flask appbuilder 提供身份验证方法
- 有时,没有一种身份验证方法适合我们的需求。这就是 Flask appbuilder 对自定义安全性和自定义身份验证的支持派上用场的地方
- 假设我们有一个微服务架构,Superset 在数据可视化方面发挥着作用。但是还有另一个微服务负责用户管理
解决方案
- 让我们实现一个自定义的安全和身份验证层
- 我正在使用超集 docker image。但是直接在主机系统上运行的超集的核心概念保持不变
解决方案源代码
- 具有自定义身份验证的独立超集的源代码(这里可以点击进入GitHub上,看代码,看config文件夹,里面congfig.py及他自己写的security.py文件)
- 与超集集成的django 演示应用程序的源代码
方法
- 使用放置在配置目录中的以下 superset_config.py 和 security.py 运行 superset docker
docker run --detach --name superset -p "8088:8088" -v $(pwd)/config:/etc/superset -v $(pwd)/data:/var/lib/superset amancevice/superset:0.25. 6
#--------------------------------------------------------- # Superset specific config #--------------------------------------------------------- ROW_LIMIT = 5000 SUPERSET_WEBSERVER_PORT = 8088 #--------------------------------------------------------- #--------------------------------------------------------- # Flask App Builder configuration #--------------------------------------------------------- # Your App secret key SECRET_KEY = '\2\1thisismyscretkey\1\2\e\y\y\h' # 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 SQLALCHEMY_DATABASE_URI = 'sqlite:////var/lib/superset/superset.db' # 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 = '' ENABLE_PROXY_FIX = True from security import CustomSecurityManager CUSTOM_SECURITY_MANAGER = CustomSecurityManager
superset_config.py hosted with ❤ by GitHub
- 注意,在 superset_config.py 中,我们尝试使用我们自己的实现来初始化 CUSTOM_SECURITY_MANAGER。
- 示例安全管理器如下所示
from flask import redirect, g, flash, request from flask_appbuilder.security.views import UserDBModelView,AuthDBView from superset.security import SupersetSecurityManager from flask_appbuilder.security.views import expose from flask_appbuilder.security.manager import BaseSecurityManager from flask_login import login_user, logout_user class CustomAuthDBView(AuthDBView): login_template = 'appbuilder/general/security/login_db.html' @expose('/login/', methods=['GET', 'POST']) def login(self): redirect_url = self.appbuilder.get_url_for_index if request.args.get('redirect') is not None: redirect_url = request.args.get('redirect') if request.args.get('username') is not None: user = self.appbuilder.sm.find_user(username=request.args.get('username')) login_user(user, remember=False) return redirect(redirect_url) elif g.user is not None and g.user.is_authenticated(): #注意经过测试,g.user.is_authenticated()似乎不应当加() return redirect(redirect_url) else: flash('Unable to auto login', 'warning') return super(CustomAuthDBView,self).login() class CustomSecurityManager(SupersetSecurityManager): authdbview = CustomAuthDBView def __init__(self, appbuilder): super(CustomSecurityManager, self).__init__(appbuilder)
security.py hosted with ❤ by GitHub
将用户直接重定向到目标页面(如特定仪表板)
很多时候,将用户重定向到某个特定的仪表板很有用。如果可以通过上述流程处理登录,那么将它们直接带到我们想要的位置会很好。
http://localhost:8088/login?username=admin&redirect=/superset/dashboard/world_health/#上面的url将自动以管理员身份登录,并将用户直接带入world_health仪表板
下一步
- 我们讨论的流程是为了演示自定义安全层的可能性以及如何使其工作。
- 如果我们在请求中传递用户名参数,它将绕过登录并将用户带入内部。
- 我们需要使认证更加严格。在上述流程之上,基于生态系统,我们可以在 CustomSecurity 层中使用 JWT 令牌或其他方式。
Superset 用户仍留在 Superset
- 这种方法并没有根除 superset 的用户管理、授权流程(角色)等,
- 它包含flask appbuilder的用户管理
- 在我们的应用程序中创建用户时,我们需要调用flask公开的REST API以在超集中创建具有相同用户名的等效用户
- 还可以通过 REST API 以编程方式分配超集中的角色。
- 这样 superset 就可以管理它自己的内部流,其他微服务可以轻松地与 superset 集成
- 这也为控制哪些仪表板应该对哪些用户等可见提供了很大的灵活性,符合 superset 的角色管理方式
覆盖 Superset html 模板
有时,需要更改超集的 UI(html 模板)。缩小范围并不难,因为开箱即用,据我所知,Superset 不支持它。
实现它的一种方法是找到超集模板目录的路径并将我们的更改安装为卷
- 在上面的例子中,我们用我们自己的内容覆盖了超集中的 navbar.html
- superset 的路径,虽然我们使用了上面的 docker 图像,但碰巧是
/usr/local/lib/python3.5/dist-package/superset/templates/...
确保这是您的情况下的路径。
version: '3.6'
services:
superset:
image: amancevice/superset:0.25.6
ports:
- "8088:8088"
volumes:
- ./superset-conf/config:/etc/superset
- ./superset-conf/templates/appbuilder/navbar.html:/usr/local/lib/python3.5/dist-packages/superset/templates/appbuilder/navbar.html
- ./superset-conf/data:/var/lib/superset
docker-compose.yml hosted with ❤ by GitHub
公共仪表板
这不适用于生产。它用于实验或进行概念验证。
#superset_config.py
PUBLIC_ROLE_LIKE_GAMMA = True
在此之后,我们需要重新运行 init 用户(如果已经运行)
> docker-compose exec superset superset-init
通过向standalone=true
url添加参数,可以在没有超集标题(导航栏等)的情况下嵌入仪表板和图表,如下所示:
http://localhost:9000/superset/dashboard/world_health/?standalone=true
我们需要向 public 角色授予数据库源权限才能使数据可见。
运行在 NGINX 后面的问题
在花了太多时间想办法让 Superset 在 NGINX 后面工作后,发现:
- Superset 使用多个静态文件引用(/static/.../...js & css)而不采用基本 url 约定
- Superset 仅在加载到根路径 (
/
)时才有效 - Superset 支持
url_for
配置baseUrl 的方式。但这仅在后端 python 层上实现得很好。它在前端(Javascript)层没有很好地实现。在某些领域,他们会执行以下操作,但会中断:
// 从flask appbuilder api 端点构建数据表
let url = '/' + modelView.toLowerCase() + '/api/read';