Superset用戶集成方案2


superset 認證分析

superset基於flask-appbuilder開發,security基於flask_appbuilder.security,翻閱其代碼,

找到入口: 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

默認使用SupersetSecurityManager,繼承自SecurityManager

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)
        
...

我們再來看SecurityManager及父類,發現,登錄是通過auth_view來控制的,默認是AUTH_DB,也就是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'))

再來看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)

對外提供'/login/'接口,讀取HTTP POST里的用戶名,密碼,然后調用auth_user_db驗證,驗證通過調用login_user生成認證信息。

因此,我們可以自定義AuthDBView,改為從我們自己的應用認證即可。

使用jwt來驗證superset

自定義CustomAuthDBView,繼承自AuthDBView,登錄時可以通過cookie或者url參數傳入jwt token,然后驗證通過的話,自動登錄,。

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()

如果用戶不存在,通過self.appbuilder.sm.add_user自動添加用戶。

然后再引入這個CustomAuthDBView,

class CustomSecurityManager(SupersetSecurityManager):
    authdbview = CustomAuthDBView

最后,再引入這個CustomSecurityManager,在superset_config.py 里增加:

from aimind_security import CustomSecurityManager
CUSTOM_SECURITY_MANAGER = CustomSecurityManager

在應用里集成superset

集成就簡單了,訪問,'SUPER_SET_URL/login/?token=jwt_token' 即可,可以通過iframe無縫集成。

轉載於:https://www.cnblogs.com/xiaoqi/p/intergate-superset.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM