注意,一下內容來自外網瀏覽器翻譯,本人使用了將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';