Flask 在Apache超集上使用KeyClope(OpenID Connect)
我从一开始就按照解释做每件事。然而,这是一个老职位,并不是所有的工作。我还试图通过将其作为FAB附加组件安装来实现自定义安全管理器,以便在我的应用程序中实现它,而不必编辑现有的超集代码 我正在运行Key斗篷4.8.1.Final和Apache超集V0.28.1 正如在文章中所解释的,超集不能很好地使用开箱即用的keydove,因为它使用的是openid2.0,而不是keydove提供的openidconnect 第一个区别是,合并拉取请求后,您不能再执行以下操作:Flask 在Apache超集上使用KeyClope(OpenID Connect),flask,openid,keycloak,apache-superset,flask-appbuilder,Flask,Openid,Keycloak,Apache Superset,Flask Appbuilder,我从一开始就按照解释做每件事。然而,这是一个老职位,并不是所有的工作。我还试图通过将其作为FAB附加组件安装来实现自定义安全管理器,以便在我的应用程序中实现它,而不必编辑现有的超集代码 我正在运行Key斗篷4.8.1.Final和Apache超集V0.28.1 正如在文章中所解释的,超集不能很好地使用开箱即用的keydove,因为它使用的是openid2.0,而不是keydove提供的openidconnect 第一个区别是,合并拉取请求后,您不能再执行以下操作: from flask_appb
from flask_appbuilder.security.sqla.manager import SecurityManager
相反,您现在必须使用:(根据updateing.md文件)
在上面提到的帖子中,海报展示了如何分别创建管理器和查看文件,但没有说明放在哪里。我将manager和view类放在同一个文件中,名为manager.py
,并将其放在FAB附加组件结构中
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
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
CUSTOM_SECURITY_MANAGER = OIDCSecurityManager
class 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))
我在这个文件中设置了CUSTOM\u SECURITY\u MANAGER
变量,而不是在superset\u config.py
中。这是因为它在那里时不工作,没有加载自定义安全管理器。读取后,我将变量移到了那里
我的client\u secret.json
文件如下所示:
{
"web": {
"realm_public_key": "<PUBLIC_KEY>",
"issuer": "https://<DOMAIN>/auth/realms/demo",
"auth_uri": "https://<DOMAIN>/auth/realms/demo/protocol/openid-connect/auth",
"client_id": "local",
"client_secret": "<CLIENT_SECRET>",
"redirect_urls": [
"http://localhost:8001/*"
],
"userinfo_uri": "https://<DOMAIN>/auth/realms/demo/protocol/openid-connect/userinfo",
"token_uri": "https://<DOMAIN>/auth/realms/demo/protocol/openid-connect/token",
"token_introspection_uri": "https://<DOMAIN>/auth/realms/demo/protocol/openid-connect/token/introspect"
}
}
在最初的帖子中,没有提到OPENID\u PROVIDERS
环境变量,因此我不确定在这里为URL放什么。我之所以这么说,是因为这是您在KeyClope上登录到客户机控制台时要点击的URL
当我运行超集时,我没有得到任何错误。我可以看到自定义安全管理器已加载。当我导航到登录屏幕时,我必须选择我的提供商,我没有得到登录表单。我选择KeyClope,因为显然没有其他东西,然后单击Login。当我单击Login时,我可以看到浏览器的地址栏中加载了一些内容,但什么也没有发生。据我所知,我应该被重定向到keydape登录表单,然后在成功登录后返回到我的应用程序,但什么也没发生。我是不是错过了什么
编辑
因此,在进一步挖掘之后,似乎我的自定义视图类加载了,但是类中的方法没有覆盖默认行为。我不知道为什么会发生这种情况,也不知道如何解决。我最终自己解决了这个问题 我最终得到的解决方案没有使用FAB附加组件,但您也不必编辑现有代码/文件 我已将manager.py文件重命名为security.py,现在看起来如下:
ADDON_MANAGERS = ['fab_addon_keycloak.manager.OIDCSecurityManager']
AUTH_TYPE = AUTH_OID
OIDC_CLIENT_SECRETS = '/usr/local/lib/python3.6/site-packages/fab_addon_keycloak/fab_addon_keycloak/client_secret.json'
OIDC_ID_TOKEN_COOKIE_SECURE = False
OIDC_REQUIRE_VERIFIED_EMAIL = False
AUTH_USER_REGISTRATION = True
AUTH_USER_REGISTRATION_ROLE = 'Gamma'
OPENID_PROVIDERS = [{
'name': 'KeyCloak',
'url': 'https://<DOMAIN>/auth/realms/demo/account'
}]
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
class 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))
class OIDCSecurityManager(SupersetSecurityManager):
authoidview = AuthOIDCView
def __init__(self,appbuilder):
super(OIDCSecurityManager, self).__init__(appbuilder)
if self.auth_type == AUTH_OID:
self.oid = OpenIDConnect(self.appbuilder.get_app)
我将security.py文件放在我的超集配置文件旁边
JSON配置文件保持不变
然后,我更改了superset_config.py文件,以包含以下行:
from security import OIDCSecurityManager
AUTH_TYPE = AUTH_OID
OIDC_CLIENT_SECRETS = <path_to_configuration_file>
OIDC_ID_TOKEN_COOKIE_SECURE = False
OIDC_REQUIRE_VERIFIED_EMAIL = False
AUTH_USER_REGISTRATION = True
AUTH_USER_REGISTRATION_ROLE = 'Gamma'
CUSTOM_SECURITY_MANAGER = OIDCSecurityManager
从安全导入OIDCSecurityManager
身份验证类型=身份验证OID
OIDC_客户_机密=
OIDC\u ID\u令牌\u COOKIE\u安全=False
OIDC\u需要\u验证\u电子邮件=错误
验证用户注册=真
验证用户注册角色='Gamma'
自定义安全管理器=OIDCSecurityManager
就这样
现在,当我导航到我的站点时,它会自动转到KeyClope登录屏幕,成功登录后,我会被重定向回我的应用程序。在superset文件夹中已经存在一个名为security.py的文件。你编辑过同一个文件吗?嗨@DeepaMG,不,我没有编辑那个文件。我的主目录“/superset/”中有一个文件夹,其中包含我的superset\u config.py文件。我将security.py和JSON文件放在superset_config.py文件旁边。如果您的superset_config.py文件位于已经有security.py文件的superset包目录中,您可以将其命名为其他名称(例如oidc_security.py),然后只需相应地更改superset_config.py文件中的引用。是的,我已经让它工作了@我现在得到的是1。在点击超集的URL时,它会将我重定向到KeyClope。2.输入凭据后,我可以看到超集。问题是我需要在KeyClope和superset中拥有相同的用户凭据。我不能只拿钥匙斗篷的证书吗?我不确定,我不这么认为。我已经设置了我的,这样,如果用户登录到KeyClope但在超集上不存在,就会自动创建一个用户。当在keydape上创建一个新用户时,它会检查超集,如果有一个用户具有相同的电子邮件地址(我认为是用户名),它会将您登录到该现有用户。在我看来,在超集中创建用户是一件好事。它允许您利用超集的内置角色来管理权限。但我正在将超集添加到我的另一个应用程序中,该应用程序已与缺少用户的KeyClope集成。我不想在超集中再次创建相同的凭据。
from security import OIDCSecurityManager
AUTH_TYPE = AUTH_OID
OIDC_CLIENT_SECRETS = <path_to_configuration_file>
OIDC_ID_TOKEN_COOKIE_SECURE = False
OIDC_REQUIRE_VERIFIED_EMAIL = False
AUTH_USER_REGISTRATION = True
AUTH_USER_REGISTRATION_ROLE = 'Gamma'
CUSTOM_SECURITY_MANAGER = OIDCSecurityManager