@sjmeyer已编写了更新的指南,该指南适用于Superset
0.28.1及更高版本。我自己还没有尝试过,但是感谢@nawazxy确认此解决方案有效。
我设法解决了自己的问题。主要问题是由我对超集使用的flask-openid插件的错误假设引起的。该插件实际上支持OpenID
2.x,但不支持OpenID
-Connect(由Keycloak实现的版本)。
解决方法是,我决定切换到flask-oidc插件。切换到新的身份验证提供程序实际上需要进行一些挖掘工作。要集成插件,我必须遵循以下步骤:
为keycloak配置flask-oidc不幸的是,flask-oidc不支持Keycloak生成的配置格式。相反,您的配置应如下所示:
{ "web": { "realm_public_key": "<YOUR_REALM_PUBLIC_KEY>", "issuer": "http://<YOUR_DOMAIN>/auth/realms/<YOUR_REALM_ID>", "auth_uri": "http://<YOUR_DOMAIN>/auth/realms/<YOUR_REALM_ID>/protocol/openid-connect/auth", "client_id": "<YOUR_CLIENT_ID>", "client_secret": "<YOUR_SECRET_KEY>", "redirect_urls": [ "http://<YOUR_DOMAIN>/*" ], "userinfo_uri": "http://<YOUR_DOMAIN>/auth/realms/<YOUR_REALM_ID>/protocol/openid-connect/userinfo", "token_uri": "http://<YOUR_DOMAIN>/auth/realms/<YOUR_REALM_ID>/protocol/openid-connect/token", "token_introspection_uri": "http://<YOUR_DOMAIN>/auth/realms/<YOUR_REALM_ID>/protocol/openid-connect/token/introspect" }}
Flask-
oidc希望该配置位于文件中。我把我的东西存放在了
client_secret.json。您可以在中配置文件的路径
superset_config.py。扩展安全管理器
首先,您需要确保烧瓶停止使用flask-openid,而广告开始使用flask-oidc。为此,您将需要创建自己的安全管理器,该管理器将flask-
oidc配置为其身份验证提供程序。我已经实现了我的安全管理器,如下所示:
from flask_appbuilder.security.manager import AUTH_OIDfrom flask_appbuilder.security.sqla.manager import SecurityManagerfrom flask_oidc import OpenIDConnectclass OIDCSecurityManager(SecurityManager):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
要在Superset中启用OpenID,以前必须将身份验证类型设置为AUTH_OID。我的安全管理器仍然执行超类的所有行为,但是用OpenIDConnect对象覆盖oid属性。此外,它用自定义视图替换默认的OpenID身份验证视图。我已经像这样实现了我的:
from flask_appbuilder.security.views import AuthOIDViewfrom flask_login import login_userfrom urllib import quoteclass AuthOIDCView(AuthOIDView):@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(): user = sm.auth_user_oid(oidc.user_getfield('email')) if user is None: info = oidc.user_getinfo(['preferred_username', 'given_name', 'family_name', 'email']) user = sm.add_user(info.get('preferred_username'), info.get('given_name'), info.get('family_name'), info.get('email'), sm.find_role('Gamma')) 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))
我的视图覆盖了/ login和/
logout端点上的行为。登录时,将运行handle_login方法。它要求用户由OIDC提供程序进行身份验证。在我们的例子中,这意味着用户将首先被重定向到Keycloak进行登录。
进行身份验证时,用户将被重定向回Superset。接下来,我们查询是否可以识别用户。如果没有,我们将基于其OIDC用户信息创建用户。最后,我们将用户登录到Superset并将他们重定向到登录页面。
注销时,我们将使这些cookie无效:
- 超集会话
- OIDC令牌
- Keycloak设置的cookie
默认情况下,Superset只处理第一个。扩展的注销方法可以照顾到所有这三点。
配置超集最后,我们需要在中添加一些参数
superset_config.py。这是我配置我的方式:
'''AUTHENTICATION'''AUTH_TYPE = AUTH_OIDOIDC_CLIENT_SECRETS = 'client_secret.json'OIDC_ID_TOKEN_cookie_SECURE = FalseOIDC_REQUIRE_VERIFIED_EMAIL = FalseCUSTOM_SECURITY_MANAGER = OIDCSecurityManagerAUTH_USER_REGISTRATION = TrueAUTH_USER_REGISTRATION_ROLE = 'Gamma'
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)