ericandrewmeadows commented on issue #8062: CUSTOM_SECURITY_MANAGER not working in 0.34.0rc1 URL: https://github.com/apache/incubator-superset/issues/8062#issuecomment-522647904 Custom SM: ``` # https://stackoverflow.com/questions/54010314/ ... # using-keycloakopenid-connect-with-apache-superset#54024394 from flask import redirect, request from flask_appbuilder.security.manager import AUTH_OID from superset.security import SupersetSecurityManager from flask_oidc import OpenIDConnect from flask_appbuilder.security.views import AuthOIDView from flask_login import login_user from urllib.parse import quote from flask_appbuilder.views import ModelView, SimpleFormView, expose import logging import os # Testing Okta from okta import UsersClient from okta.framework.ApiClient import ApiClient # DELETE import json DEFAULT_USER_ROLE = 'Gamma' USER_ROLE_TRANSLATION_DICT = { 'Charts Admin': 'Admin', 'Charts Alpha Users': 'Alpha', 'software': 'Software', } class AuthOIDCView(AuthOIDView): def get_given_and_family_name_from_name(self, info): name = info.get('name') first_space_location = name.find(' ') given_name = info.get('given_name', name[:first_space_location]) family_name = info.get('family_name', name[first_space_location+1:]) return (given_name, family_name) def get_user_info(self, okta_client, uid): response = ApiClient.get_path(okta_client, '/{0}'.format(uid)) user_info = json.loads(response.text) return user_info def get_account_creation_info(self, user_info): profile = user_info['profile'] username = profile.get('login') first_name = profile.get('firstName') last_name = profile.get('lastName') email = profile.get('email') return (username, first_name, last_name, email) def create_user(self, sm, user_info): (username, first_name, last_name, email) =\ self.get_account_creation_info(user_info) role = sm.find_role(DEFAULT_USER_ROLE) user = sm.add_user(username, first_name, last_name, email, role) return user def get_group_info(self, okta_client, uid): response = ApiClient.get_path(okta_client, '/{0}/groups'.format(uid)) group_info = json.loads(response.text) return group_info def get_group_membership(self, group_info): group_membership = [group["profile"]["name"] for group in group_info] return group_membership def get_or_create_roles(self, sm, group_membership): roles = [ sm.add_role(USER_ROLE_TRANSLATION_DICT.get(group, group)) for group in group_membership ] return roles def update_user_roles(self, sm, user, group_info): group_membership = self.get_group_membership(group_info) roles = self.get_or_create_roles(sm, group_membership) existing_roles = user.roles for role in roles: if role in existing_roles: continue user.roles.append(role) logging.info(f'Role added to {user.username}: {role.name}') return user @expose('/login/', methods=['GET', 'POST']) def login(self, flag=True): sm = self.appbuilder.sm oidc = sm.oid @self.appbuilder.sm.oid.require_login def handle_login(): uid = oidc.user_getfield("sub") user = sm.auth_user_oid(uid) okta_client = UsersClient( os.environ['ORG_URL'], os.environ['OKTA_AUTH_TOKEN'] ) user_info = self.get_user_info(okta_client, uid) user_active = user_info['status'] == "ACTIVE" if not user_active: return if user is None: user = self.create_user(sm, user_info) logging.info(f"User: {user}") group_info = self.get_group_info(okta_client, uid) user = self.update_user_roles(sm, user, group_info) sm.update_user(user) login_user(user, remember=False) return redirect(self.appbuilder.get_url_for_index) return handle_login() @expose('/logout/', methods=['GET', 'POST']) def logout(self): oidc = self.appbuilder.sm.oid oidc.logout() super(AuthOIDCView, self).logout() redirect_url = request.url_root.strip('/') + self.appbuilder.get_url_for_login return redirect(oidc.client_secrets.get('issuer') + '/protocol/openid-connect/logout?redirect_uri=' + quote(redirect_url)) class OIDCSecurityManager(SupersetSecurityManager): def __init__(self, appbuilder): super(OIDCSecurityManager, self).__init__(appbuilder) if self.auth_type == AUTH_OID: self.oid = OpenIDConnect(self.appbuilder.get_app) self.authoidview = AuthOIDCView ```
---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org With regards, Apache Git Services --------------------------------------------------------------------- To unsubscribe, e-mail: notifications-unsubscr...@superset.apache.org For additional commands, e-mail: notifications-h...@superset.apache.org