【Superset】自定义授权认证,接入内部系统二次开发
想要将内部系统认证与superset打通,必须要了解superset的认证体系。
Superset的认证体系
Superset的认证体系可以通过以下几种方式进行配置:
-
基于LDAP认证:Superset可以集成LDAP以验证用户身份。在这种情况下,Superset将根据LDAP中的用户信息进行身份验证,并从LDAP中获取用户属性和组织结构信息。
-
基于OAuth2认证:Superset支持OAuth2认证和授权。在这种情况下,Superset将重定向用户到OAuth2提供商的登录页,并在用户授权时获取访问令牌以进行身份验证。
-
本地认证:Superset还支持本地认证,其中用户可以在Superset中创建帐户并设置密码。在这种情况下,Superset将使用这些凭据来验证用户身份。
无论使用哪种认证方式,管理员都可以控制哪些用户可以访问Superset中的特定资源。例如,可以定义哪些用户可以访问特定的数据源、仪表板或视图。此外,管理员还可以定义角色和权限,以控制用户在Superset中的操作范围。
二次开发,重写认证

系统配置文件: \superset\config.py
配置缓存
在config.py里面配置
Reids_Url = '127.0.0.1'
Reids_Port = 6379# Cache for datasource metadata and query results
DATA_CACHE_CONFIG: CacheConfig = {'CACHE_TYPE': 'redis', # 使用 Redis'CACHE_REDIS_HOST': Reids_Url, # 配置域名'CACHE_REDIS_PORT': Reids_Port , # 配置端口号'CACHE_REDIS_URL': 'redis://' + Reids_Url + ':' + str(Reids_Port)}
配置认证管理类
在config.py里面配置
from superset.custom_sso_security_manager import CustomSsoSecurityManagerCUSTOM_SECURITY_MANAGER = CustomSsoSecurityManager
新建类
自定义视图:MyAuthRemoteUserView
class MyAuthRemoteUserView(AuthRemoteUserView):# this front-end template should be put under the folder `superset/templates/appbuilder/general/security`# so that superset could find this templates to renderlogin_template = 'appbuilder/general/security/login_my.html'title = "My Login"@expose('/test', methods=['GET', 'POST'])def test(self):data = {}# for name in request.environ:# if (type(request.environ[name]) == str or type(request.environ[name]) == int):# data[name] = request.environ[name]# return dataresponse = _wz_redirect('/login/')print(response.headers)return response# this method is going to overwrite# https://github.com/dpgaspar/Flask-AppBuilder/blob/master/flask_appbuilder/security/views.py#L556@expose('/login/', methods=['GET', 'POST'])def login(self):next_url = get_real_scheme_next_url()if g.user and g.user.get_id():return redirect(next_url)token= request.cookies.get("token")if (tokenNone or token== ''):print("token未获取到!")return redirect(CustomSsoSecurityManager.CAS_LOGIN_SERVER_URL + "?redirect_uri=" + self.get_login_redirect_uri())manager = self.appbuilder.smheader = {"cookie": "token=" + userToken,}result = requests.post(CustomSsoSecurityManager.CAS_CHECK_SERVER_URL,headers=header)resultWarp = json.loads(result.content)if (not resultWarp["success"]):return redirect(CustomSsoSecurityManager.CAS_LOGIN_SERVER_URL + "?redirect_uri=" + self.get_login_redirect_uri())cas_user = resultWarp["result"]username = cas_user['username']user = manager.find_user(username=username)print(user)# User does not exist, create one if auto user registration.if user is None and manager.auth_user_registration:user = manager.add_user(# All we have is REMOTE_USER, so we set# the other fields to blank.username=username,first_name=cas_user['name'],last_name='',email=username,role=manager.find_role(manager.auth_user_registration_role))# If user does not exist on the DB and not auto user registration,# or user is inactive, go away.elif user is None or (not user.is_active):logger.info(LOGMSG_WAR_SEC_LOGIN_FAILED.format(username))return Nonemanager.update_user_auth_stat(user)login_user(user, remember=False)session[SESSION_CAS_USER] = cas_usersession[SESSION_HCP] = hcpCustomSsoSecurityManager.get_data_auth(hcp, cas_user['id'])return redirect(next_url)def get_Login_url(self):return get_root_url() + '/login/'def get_login_redirect_uri(self):next_url = get_real_scheme_next_url()return parse.quote(self.get_Login_url() + "?next=" + next_url)@expose("/logout/")def logout(self):logout_user()userToken= request.cookies.get("token")if userToken:header = {"cookie": "token=" + userToken,}data = {"token": hcp}requests.post(CustomSsoSecurityManager.CAS_LOGINOUT_SERVER_URL, json=data,headers=header)if CustomSsoSecurityManager.SESSION_CAS_USER in session:session.pop(CustomSsoSecurityManager.SESSION_CAS_USER)if CustomSsoSecurityManager.SESSION_HCP in session:session.pop(CustomSsoSecurityManager.SESSION_HCP)if CustomSsoSecurityManager.SESSION_CAS_DATA_AUTH in session:session.pop(CustomSsoSecurityManager.SESSION_CAS_DATA_AUTH)return redirect(CustomSsoSecurityManager.CAS_LOGIN_SERVER_URL + '?redirect_uri=' + self.get_Login_url())
自定义管理类:CustomSsoSecurityManager
class CustomSsoSecurityManager(SupersetSecurityManager):authremoteuserview = MyAuthRemoteUserViewSESSION_CAS_USER = "_CAS_USER"SESSION_CAS_DATA_AUTH = "_CAS_DATA_AUTH"CAS_LOGIN_SERVER_URL = NoneCAS_CHECK_SERVER_URL = NoneCAS_LOGINOUT_SERVER_URL = NoneCAS_DATA_AUTH_URL = Noneconfig = Nonedef __init__(self, appbuilder):super().__init__(appbuilder)CustomSsoSecurityManager.get_cas_url(appbuilder.app.config)@classmethoddef get_cas_url(cls, config):cls.config = configcls.CAS_LOGIN_SERVER_URL = cls.config.get("SSO_LOGIN_URL")cls.CAS_CHECK_SERVER_URL = cls.config.get("SSO_SERVER_API_URL") + '/getCurrentUser'cls.CAS_LOGINOUT_SERVER_URL = cls.config.get("SSO_SERVER_API_URL") + '/logout'cls.CAS_DATA_AUTH_URL = cls.config.get("SSO_SERVER_API_URL") + '/getDataAuthByUserId'# 获取数据权限@classmethoddef get_data_auth(cls, token, user_id):data = {"moduleId": "SAAS_BI_DATA_AUTHORITY", "userId": user_id}result = requests.post(cls.CAS_DATA_AUTH_URL, json=data,headers=header)# print(result.content)result_warp = json.loads(result.content)if (not result_warp["success"]):else:session[cls.SESSION_CAS_DATA_AUTH] = result_warp['result']def load_user(self, pk):return self.get_user_by_id(int(pk))def setCache(self, key, value, expire):r.set(key, value)if expire is None or expire < 10:expire = 60 * 5r.expire(key, expire)def load_user3(self):token= request.cookies.get("token")biUserCacheData = {}if (tokenis None or token== ''):user = self.lm.anonymous_user()return self.lm._update_request_context_with_user(user)biUserKey = tokenbiUserInfoCache = NoneuserCache = NonebiUserCacheData = Noneif r.hexists(biUserKey, "apiUserInfo"):biUserInfoCache = r.hget(biUserKey, "apiUserInfo")userCache = biUserInfoCache.decode()biUserCacheData = json.loads(userCache)if biUserCacheData["success"] == False:biUserInfoCache = Noneif biUserInfoCache:cas_user = biUserCacheData["result"]session[CustomSsoSecurityManager.SESSION_CAS_USER] = cas_usersession[CustomSsoSecurityManager.SESSION_HCP] = tokenusername = cas_user['username']manager = self.appbuilder.smuser = manager.find_user(username=username)apiUserAuth = r.hget(biUserKey, "apiUserAuth")result_warp = json.loads(apiUserAuth.decode())if (not result_warp["success"]):user = self.lm.anonymous_user()return self.lm._update_request_context_with_user(user)else:session[self.SESSION_CAS_DATA_AUTH] = result_warp['result']else:manager = self.appbuilder.smheader = {"cookie": "token=" + token}result = requests.post(CustomSsoSecurityManager.CAS_CHECK_SERVER_URL,headers=header)resultWarp = json.loads(result.content)r.hset(biUserKey, "apiUserInfo", result.content)if (not resultWarp["success"]):user = self.lm.anonymous_user()return self.lm._update_request_context_with_user(user)cas_user = resultWarp["result"]username = cas_user['username']user = manager.find_user(username=username)# User does not exist, create one if auto user registration.if user is None and manager.auth_user_registration:user = manager.add_user(# All we have is REMOTE_USER, so we set# the other fields to blank.username=username,first_name=cas_user['name'],last_name='',email=username,role=manager.find_role(manager.auth_user_registration_role))# If user does not exist on the DB and not auto user registration,# or user is inactive, go away.elif user is None or (not user.is_active):logger.info(LOGMSG_WAR_SEC_LOGIN_FAILED.format(username))user = self.lm.anonymous_user()return self.lm._update_request_context_with_user(user)manager.update_user_auth_stat(user)login_user(user, remember=False)session[CustomSsoSecurityManager.SESSION_CAS_USER] = cas_usersession[CustomSsoSecurityManager.SESSION_HCP] = tokenheader = {"cookie": "token=" + token}data = {"moduleId": "SAAS_BI_DATA_AUTHORITY", "userId": cas_user['id']}result = requests.post(self.CAS_DATA_AUTH_URL, json=data,headers=header)# print(result.content)result_warp = json.loads(result.content)r.hset(biUserKey, "apiUserAuth", result.content)if (not result_warp["success"]):user = self.lm.anonymous_user()return self.lm._update_request_context_with_user(user)else:session[self.SESSION_CAS_DATA_AUTH] = result_warp['result']return self.lm._update_request_context_with_user(user)def create_login_manager(self, app: Flask) -> LoginManager:lm = super().create_login_manager(app)lm.request_loader(self.request_loader)lm._load_user = self.load_user3self.lm = lmreturn lm@classmethoddef get_data_auth_from_session(cls):return session[cls.SESSION_CAS_DATA_AUTH]@classmethoddef get_cas_user_from_session(cls):return session[cls.SESSION_CAS_USER]
参考资料:
- zhuanlan.zhihu.com/p/516553212
相关文章:
【Superset】自定义授权认证,接入内部系统二次开发
想要将内部系统认证与superset打通,必须要了解superset的认证体系。 Superset的认证体系 Superset的认证体系可以通过以下几种方式进行配置: 基于LDAP认证:Superset可以集成LDAP以验证用户身份。在这种情况下,Superset将根据LDAP…...
私有云:【1】ESXI的安装
私有云:【1】ESXI的安装 1、使用VMware Workstation创建虚拟机2、启动配置虚拟机3、登录ESXI管理台 1、使用VMware Workstation创建虚拟机 新建虚拟机 选择典型安装 稍后安装操作系统 选择VMware ESXI 选择虚拟机安装路径 硬盘设置300G或者更多 自定义硬件 内存和处…...
Mac怎么删除文件和软件?苹果电脑删除第三方软件方法
Mac删除程序这个话题为什么一直重复说或者太多人讨论呢?因为如果操作不当,可能会导致某些不好的影响。因为Mac电脑如果有太多无用的应用程序,很有可能会拖垮Mac系统的运行速度。或者如果因为删除不干净,导致残留文件积累在Mac电脑…...
【开题报告】基于微信小程序的旅游攻略分享平台的设计与实现
1.研究背景及意义 旅游已经成为现代人生活中重要的组成部分,人们越来越热衷于探索新的目的地和体验不同的文化。然而,对于旅游者来说,获取准确、可靠的旅游攻略信息并不容易。传统的旅游攻略书籍或网站往往无法提供实时、个性化的建议。因此…...
布隆过滤器(Bloom Filter)初学习
目录 1、布隆过滤器是什么 2、布隆过滤器的优缺点 3、使用场景 4、⭐基于Redis的布隆过滤器插件安装 4.1 下载布隆过滤器 4.2 创建文件夹并上传文件 4.3 安装gcc 4.4 解压RedisBloom压缩包 4.5 在解压好的文件夹下输入make 4.6 将编译的好的插件拷贝到docker redis容…...
“深入探讨操作系统和虚拟化技术“
目录 引言1.操作系统1.1.什么是操作系统1.2.常见操作系统1.3.个人版本和服务器版本的区别1.4.Linux的各个版本 2.安装VMWare虚拟机1.VMWare虚拟机介绍2.VMWare虚拟机安装3.VMWare虚拟机配置 3.安装配置Windows Server 2012 R24.完成电脑远程访问电脑5.服务器环境搭建配置jdk配置…...
远程连接异地主机可能遇到的问题及处理
0.现状 公司的一套系统内部有多个节点的内网,要把数据上传至客户的办公网环境中的服务器。客户办公网为我们提供了一台类似路由的设备,办公网无法让内网地址的数据包透传至服务器。现场条件所限,只有有限数量的技术服务人员可以维持…...
使用 PointNet 进行3D点集(即点云)的分类
点云分类 介绍 无序3D点集(即点云)的分类、检测和分割是计算机视觉中的核心问题。此示例实现了开创性的点云深度学习论文PointNet(Qi 等人,2017)。 设置 如果使用 colab 首先安装 trimesh !pip install trimesh。 import os import glob import trimesh import numpy as…...
高通平台GPIO引脚复用指导
高通平台GPIO引脚复用指导 1. 概述1.1 平台有多少个GPIO?1.2 这些GPIO都有哪些可复用的功能? 2. 软件配置2.1 TZ侧GPIO配置2.2 SBL侧GPIO配置2.3 AP侧GPIO配置2.3.1 Linux DTS机制与设备驱动模型概述2.3.2高通平台的pinctrl控制器2.3.2.1 SDX12 CPU pinc…...
华为机试题:HJ5 进制转换
目录 第一章、算法题1.1)题目描述1.2)解题思路与答案1.3)派仔的解题思路与答案1.3)牛客链接 友情提醒: 先看文章目录,大致了解文章知识点结构,点击文章目录可直接跳转到文章指定位置。 第一章、算法题 1.…...
面试算法37:小行星碰撞
题目 输入一个表示小行星的数组,数组中每个数字的绝对值表示小行星的大小,数字的正负号表示小行星运动的方向,正号表示向右飞行,负号表示向左飞行。如果两颗小行星相撞,那么体积较小的小行星将会爆炸最终消失…...
ROS学习记录2018.7.10
ROS学习记录2018.7.10 1.ROS基础了解 开源机器人操作系统ROS(robot operation system) 分级: 1.计算图集(一种网络结构) 1.节点:执行运算的进程(做基础处理的单元)2.消息&#x…...
OPC UA:工业领域的“HTML”
OPC UA是工业自动化领域的一项重要的通信协议。它的特点是包括了信息模型构建方法。能够建立工业领域各种事物的信息模型。在工业自动化行业,OPCUA 类似互联网行业的HTTP协议和“HTML”语言。能够准确,可靠地描述复杂系统中各个元素,并且实现…...
【golang】Windows环境下Gin框架安装和配置
Windows环境下Gin框架安装和配置 我终于搞定了Gin框架的安装,花了两三个小时,只能说道阻且长,所以写下这篇记录文章 先需要修改一些变量,这就需要打开终端,为了一次奏效,我们直接设置全局的: …...
多测师肖sir_高级金牌讲师__接口测试之tonken (5.6)
接口测试之tonken 网站:http://shop.duoceshi.com/login?redirect2Fdashboard 第一个接口:uiid接口 uiid接口url:http://manage.duoceshi.com/auth/code test中语句: var jsonData JSON.parse(responseBody); postman.setEnvi…...
C++常见面试问题之内存对齐
一、内存对齐是什么 1.内存对齐是什么 还是用一个例子带出这个问题,看下面的小程序,理论上,32位系统下,int占4byte,char占一个byte,那么将它们放到一个结构体中应该占415byte;但是实际上&…...
网络协议--TCP:传输控制协议
17.1 引言 本章将介绍TCP为应用层提供的服务,以及TCP首部中的各个字段。随后的几章我们在了解TCP的工作过程中将对这些字段作详细介绍。 对TCP的介绍将由本章开始,并一直包括随后的7章。第18章描述如何建立和终止一个TCP连接,第19和第20章将…...
网络协议--BOOTP:引导程序协议
16.1 引言 在第5章我们介绍了一个无盘系统,它在不知道自身IP地址的情况下,在进行系统引导时能够通过RARP来获取它的IP地址。然而使用RARP有两个问题:(1)IP地址是返回的唯一结果;(2)…...
33基于MATLAB的对RGB图像实现中值滤波,均值滤波,维纳滤波。程序已通过调试,可直接运行。
基于MATLAB的对RGB图像实现中值滤波,均值滤波,维纳滤波。程序已通过调试,可直接运行。 33 MATLAB、图像处理、维纳滤波 (xiaohongshu.com)...
WPF十六(页面内嵌加载)
在WPF中进行页面内嵌的加载 当存在一定需求时,比如当前页面C左侧是一个A页面,右侧是一个B页面,A页面是一个公用页面时,此时只需要做内嵌A页面,然后B页面进行正常处理,既可以节省时间,又做到了WP…...
禅道最新22.0+ 手动删除无法安装之清理卸载办法
禅道项目管理软件卸载方法详解:如何彻底清除所有相关文件和配置在企业或个人开发环境中,禅道(Zentao)作为一款广受欢迎的开源项目管理工具,因其功能全面、易用性强而被广泛使用。然而,在某些情况下…...
用风水学重构代码:周易卦象优化系统架构
在软件工程领域,系统架构的优化与性能调优一直是技术专家们不懈探索的核心课题。传统的优化思路往往聚焦于算法效率、资源调度、中间件配置等技术维度。然而,一个更具颠覆性的视角正在悄然兴起:将源自古老东方智慧的《周易》卦象体系…...
AI 编程盛行的时代,为什么 “『DC- WFW』” 仍然具有必要性?
AI训练存储选型的演进路线 第一阶段:单机直连时代 早期的深度学习数据集较小,模型训练通常在单台服务器或单张GPU卡上完成。此时直接将数据存储在训练机器的本地NVMe SSD/HDD上。 其优势在于IO延迟最低,吞吐量极高,也就是“数据离…...
公司 SEO 网站优化服务如何应对搜索引擎算法更新_公司 SEO 网站优化服务如何提高网站的曝光度
公司 SEO 网站优化服务如何应对搜索引擎算法更新 在数字化时代,搜索引擎算法的更新频繁,给公司的SEO网站优化服务带来了不小的挑战。搜索引擎不断优化其算法,以提升用户体验和搜索结果的相关性。这种变化往往会对网站的排名和曝光度产生直接…...
nerdctl 入门指南:从安装到容器管理
1. 为什么选择 nerdctl 管理容器? 如果你已经熟悉 Docker 的命令行工具,那么第一次接触 nerdctl 时会感到非常亲切。作为 containerd 生态中的明星工具,nerdctl 提供了与 Docker CLI 高度兼容的操作体验,但底层却采用了更轻量级的…...
Asian Beauty Z-Image Turbo实战:用nvidia-smi监控显存,小白也能轻松调优
Asian Beauty Z-Image Turbo实战:用nvidia-smi监控显存,小白也能轻松调优 如果你正在使用Asian Beauty Z-Image Turbo生成东方风格人像,是否遇到过生成过程中程序突然崩溃,或者生成速度越来越慢的情况?这些问题的罪魁…...
React Native Boilerplate组件库终极指南:AssetByVariant与IconByVariant高级用法
React Native Boilerplate组件库终极指南:AssetByVariant与IconByVariant高级用法 【免费下载链接】react-native-boilerplate A React Native template for building solid applications 🐙, using JavaScript 💛 or Typescript Ὁ…...
tealdeer与其他tldr客户端的终极对比分析:哪个更适合你的命令行工作流?
tealdeer与其他tldr客户端的终极对比分析:哪个更适合你的命令行工作流? 【免费下载链接】tealdeer A very fast implementation of tldr in Rust. 项目地址: https://gitcode.com/gh_mirrors/te/tealdeer tealdeer是一款用Rust开发的tldr客户端&a…...
【数据手册解读12】发光二极管-LED
发光二极管-LED 国星光电 LED IF:正向电流,...
【限时开源】我们刚在GitHub归档的Python MCP生产模板——含自动证书轮换、配置热重载、灰度指令通道(仅开放72小时)
第一章:Python MCP服务器开发模板概览与核心设计哲学Python MCP(Model-Controller-Protocol)服务器开发模板是一个面向协议驱动、可插拔架构的轻量级服务框架,专为构建高内聚、低耦合的远程控制与设备交互服务而设计。它并非传统W…...
