为了统一和安全考虑,将superset接入公司账号系统,使用员工现有邮箱和密码作为登录方式 env:superset 0.36.0
Superset使用FAB(Flask-Appbuilder)实现了用户权限功能,登录认证框架。
FAB支持以下几种认证方式:
这里使用的是REMOTE_USER方式,通过调用remote server api,从remote web server获取用户的认证信息,也就是公司的登录系统,认证通过则将用户信息保存到db中,只要验证用户的session没有过期,就可以直接访问网站。授权验证通过后,通过appbuilder.sm.add_user,将用户添加到superset用户库中,后面进行该用户的应用内权限管理。
1.首先是配置 通过阅读superset/config.py中的代码, 如果需要自行修改配置, 创建superset_config.py文件。
在superset 创建自定义配置文件 superset_config.py
添加以下内容,替换默认CUSTOM_SECURITY_MANAGER中使用的SecurityManager. 然后写一个CustomSecurityManager类去继承SecurityManager,
from superset.custom_security import CustomSecurityManager CUSTOM_SECURITY_MANAGER = CustomSecurityManager
2.修改登录页 /root/incubator-superset/superset/templates/appbuilder/navbar_right.html
主要是为了修改登录和登出按钮的连接跳转。
修改为以下内容: 将110行注释,替换 将125行注释替换,添加124行
109 <li><a href="{{appbuilder.get_url_for_userinfo}}"><span class="fa fa-fw fa-user"></span>{{_("Profile")}}</a></li> 110 <li><a href="/sso/logout"><span class="fa fa-fw fa-sign-out"></span>{{_("Logout")}}</a></li> 111 <!--<li><a href="{{appbuilder.get_url_for_logout}}"><span class="fa fa-fw fa-sign-out"></span>{{_("Logout")}}</a></li>--> 123 {% else %} 124 <li><a href="/sso/login"> 125 <!--<li><a href="{{appbuilder.get_url_for_login}}">--> 126 <i class="fa fa-fw fa-sign-in"></i>SSO_{{_("Login")}}</a></li> 127 {% endif %}
3.自定义方法继承SecurityManager 写一个custom_security.py类去继承SecurityManager, 重写一些view自定义登录效果。
在superset目录新建custom_security.py脚本。
每次将请求中的ticket,向remote server进行验证,如果有效,直接登录成功,否则重新登录sso进行授权。成功授权后判断用户是否已经出现在superset用户库中,如果没有添加该用户,指定账户名为用户名,密码默认为用户名。
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 import requests import superset_config class CustomAuthDBView(AuthDBView): @expose('/sso/login/', methods=['GET']) def sso_login(self): print("------------ login", request.args) if request.args.get('ticket') is not None: r = requests.get(**login_url**, verify=False) print("------------ validate", r.json()['username']) username = r.json()['username'] user = self.appbuilder.sm.find_user(username=username) if user is not None: print("------------ find user", user) login_user(user, remember=False) return redirect(self.appbuilder.get_url_for_index) else: user = self.appbuilder.sm.add_user( username=username, first_name=username.split('.')[0], last_name=username.split('.')[1], password = username, email=username, role=self.appbuilder.sm.find_role(self.appbuilder.sm.auth_user_registration_role)) print("------------ new user", user) login_user(user, remember=False) return redirect(self.appbuilder.get_url_for_index) else: return redirect(***login_url***) @expose('/sso/logout/', methods=['GET']) def sso_logout(self): print("------------ logout", logout_url) return redirect(**logout_url**) class CustomSecurityManager(SupersetSecurityManager): authdbview = CustomAuthDBView def __init__(self, appbuilder): super(CustomSecurityManager, self).__init__(appbuilder)
刷新superset,查看登录页面右上角登录按钮。
参考 :