Superset is an incubator project of apache, positioned as a modern, quasi-commercial BI system
superset
Apache Superset (incubating) is a modern, enterprise-ready business intelligence web application
Superset is an incubation project of apache, positioned as a modern, quasi-commercial BI system.
Superset (Caravel) is an open source data analysis and visualization platform of Airbnb (known as Caravel, Panoramix). The main features of this tool are self-help analysis, custom dashboard, visualization of analysis results (export), user/role rights control, and integration of an SQL editor. It can be used to edit and query SQL.
Through superset, beautiful statistical charts can be made.
preview
Supset installation
We use docker directly here
git clone https://github.com/apache/incubator-superset/ cd incubator-superset/contrib/docker # prefix with SUPERSET_LOAD_EXAMPLES=yes to load examples: docker-compose run --rm superset ./docker-init.sh # you can run this command everytime you need to start superset now: docker-compose up
When the build is complete, visit http://localhost:8088.
If you want to integrate your own applications, you need to solve authentication first.
Supset authentication analysis
Supset is developed based on flask-appbuilder, security is based on flask_appbuilder.security, and its code is scanned.
Find the entrance: superset/_init_.py:
custom_sm = app.config.get('CUSTOM_SECURITY_MANAGER') or SupersetSecurityManager if not issubclass(custom_sm, SupersetSecurityManager): raise Exception( """Your CUSTOM_SECURITY_MANAGER must now extend SupersetSecurityManager, not FAB's security manager. See [4565] in UPDATING.md""") appbuilder = AppBuilder( app, db.session, base_template='superset/base.html', indexview=MyIndexView, security_manager_class=custom_sm, update_perms=get_update_perms_flag(), ) security_manager = appbuilder.sm
Superset Security Manager is used by default, inherited from Security Manager:
class SupersetSecurityManager(SecurityManager): def get_schema_perm(self, database, schema): if schema: return '[{}].[{}]'.format(database, schema) def can_access(self, permission_name, view_name): """Protecting from has_access failing from missing perms/view""" user = g.user if user.is_anonymous: return self.is_item_public(permission_name, view_name) return self._has_view_access(user, permission_name, view_name) ...
Looking at the Security Manager and its parent class, we find that login is controlled by auth_view, which defaults to AUTH_DB, or AuthDBView.
""" Override if you want your own Authentication LDAP view """ authdbview = AuthDBView if self.auth_type == AUTH_DB: self.user_view = self.userdbmodelview self.auth_view = self.authdbview() @property def get_url_for_login(self): return url_for('%s.%s' % (self.sm.auth_view.endpoint, 'login'))
Look again at authdbview:
class AuthDBView(AuthView): login_template = 'appbuilder/general/security/login_db.html' @expose('/login/', methods=['GET', 'POST']) def login(self): if g.user is not None and g.user.is_authenticated: return redirect(self.appbuilder.get_url_for_index) form = LoginForm_db() if form.validate_on_submit(): user = self.appbuilder.sm.auth_user_db(form.username.data, form.password.data) if not user: flash(as_unicode(self.invalid_login_message), 'warning') return redirect(self.appbuilder.get_url_for_login) login_user(user, remember=False) return redirect(self.appbuilder.get_url_for_index) return self.render_template(self.login_template, title=self.title, form=form, appbuilder=self.appbuilder)
Provide the'/ login/'interface to the outside world, read the user name and password in HTTP POST, then call auth_user_db authentication to verify that the authentication information is generated by calling login_user.
Therefore, we can customize AuthDBView and authenticate it from our own application.
Verify superset with jwt
Custom AuthDBView, inherited from AuthDBView, can be imported into jwt token through cookie or url parameters when login, and then authenticated, automatically login.
import jwt import json class CustomAuthDBView(AuthDBView): login_template = 'appbuilder/general/security/login_db.html' @expose('/login/', methods=['GET', 'POST']) def login(self): token = request.args.get('token') if not token: token = request.cookies.get('access_token') if token is not None: jwt_payload = jwt.decode(token,'secret',algorithms=['RS256']) user_name = jwt_payload.get("user_name") user = self.appbuilder.sm.find_user(username=user_name) if not user: role_admin = self.appbuilder.sm.find_role('Admin') user = self.appbuilder.sm.add_user(user_name, user_name, 'aimind', user_name + "@aimind.com", role_admin, password = "aimind" + user_name) if user: login_user(user, remember=False) redirect_url = request.args.get('redirect') if not redirect_url: redirect_url = self.appbuilder.get_url_for_index return redirect(redirect_url) else: return super(CustomAuthDBView,self).login() else: flash('Unable to auto login', 'warning') return super(CustomAuthDBView,self).login()
If the user does not exist, the user is automatically added through self.appbuilder.sm.add_user.
Then the Custom AuthDBView is introduced.
class CustomSecurityManager(SupersetSecurityManager): authdbview = CustomAuthDBView
Finally, the Custom Security Manager is introduced and added in superset_config.py:
from aimind_security import CustomSecurityManager CUSTOM_SECURITY_MANAGER = CustomSecurityManager
Integrating Supset in Applications
Integration is simple, access,'SUPER_SET_URL/login/?token=jwt_token', can be seamlessly integrated through iframe.
Author: Jadepeng
Origin: jqpeng's technical notebook-- http://www.cnblogs.com/xiaoqi
Your support is the biggest encouragement to bloggers. Thank you for your careful reading.
Copyright of this article belongs to the author. Reproduction is welcomed, but without the author's consent, the statement must be retained, and the link of the original text should be given clearly on the page of the article, otherwise the right to pursue legal liability will be reserved.