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但是直接在主机系统上运行的超集的核心概念保持不变

解决方案源代码

方法

 

  • 使用放置在配置目录中的以下 superset_config.py 和 security.py 运行 superset docker
#---------------------------------------------------------
# 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

自定义 suserset_config.py
  • 注意,在 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


将用户直接重定向到目标页面(如特定仪表板)

很多时候,将用户重定向到某个特定的仪表板很有用。如果可以通过上述流程处理登录,那么将它们直接带到我们想要的位置会很好。

下一步

  • 我们讨论的流程是为了演示自定义安全层的可能性以及如何使其工作。
  • 如果我们在请求中传递用户名参数,它将绕过登录并将用户带入内部。
  • 我们需要使认证更加严格。在上述流程之上,基于生态系统,我们可以在 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

公共仪表板

这不适用于生产。它用于实验或进行概念验证。

在此之后,我们需要重新运行 init 用户(如果已经运行)

通过向standalone=trueurl添加参数,可以在没有超集标题(导航栏等)的情况下嵌入仪表板和图表,如下所示:

我们需要向 public 角色授予数据库源权限才能使数据可见。

运行在 NGINX 后面的问题

在花了太多时间想办法让 Superset 在 NGINX 后面工作后,发现:

  • Superset 使用多个静态文件引用(/static/.../...js & css)而不采用基本 url 约定
  • Superset 仅在加载到根路径 ( /)时才有效
  • Superset 支持url_for配置baseUrl 的方式。但这仅在后端 python 层上实现得很好。它在前端(Javascript)层没有很好地实现。在某些领域,他们会执行以下操作,但会中断:

 

posted @ 2021-08-12 09:48  数据行者  阅读(2606)  评论(0编辑  收藏  举报