如何在 Flask-Appbuilder 中为 OAuth2.0 使用自定义提供程序 [keycloak]?
Posted
技术标签:
【中文标题】如何在 Flask-Appbuilder 中为 OAuth2.0 使用自定义提供程序 [keycloak]?【英文标题】:How do I use a Custom Provider [keycloak] for OAuth2.0 in Flask-Appbuilder? 【发布时间】:2019-05-23 13:14:05 【问题描述】:我正在尝试将 keycloak 实现为 OAuth2.0 提供程序。我拥有所有必要的 OAUTH_PROVIDER 信息,并且我已经声明了 AUTH_TYPE、AUTH_USER_REGISTRATION、AUTH_USER_REGISTRATION_ROLE (参见下面的代码)
AUTH_TYPE = AUTH_OAUTH
AUTH_USER_REGISTRATION = True
AUTH_USER_REGISTRATION_ROLE = "Public"
OAUTH_PROVIDERS = [
‘name’: ‘provider_name’,
‘icon’: ‘fa-icon’,
’token_key’: ‘access_token’,
‘remote_app’:
‘base_url’: ‘https://www.base_url.com‘,
‘request_token_params’:
‘scope’: ‘email profile’
,
‘request_token_url’: None,
‘access_token_url’: ‘https://www.access_token_url.com’,
‘authorize_url': ‘https://www.authorize_url.com',
‘consumer_key’: ‘PROVIDER_OAUTH_KEY’,
‘consumer_secret’: ‘PROVIDER_OAUTH_SECRET’
]
因为这是一个自定义提供程序(除了通常的 google、facebook、...提供程序),在我的安全管理器中,我已经覆盖了 flask 中声明的 get_oauth_user_info 函数-appbuilder manager.py
def get_oauth_user_info(self, provider, response=None):
logging.debug("Oauth2 provider: 0.".format(provider))
me = self.appbuilder.sm.oauth_remotes[provider].get("user")
logging.error(me)
return
"preferred_username": me.data.get("preferred_username",""),
"first_name": me.data.get("given_name", ""),
"last_name": me.data.get("family_name", ""),
"email": me.data.get("email", "")
我希望应用程序被重定向到 keycloak 登录页面,但是在发布请求时会引发以下错误:
DEBUG:flask_oauthlib:Request 'https://...' with 'POST' method
ERROR:flask_appbuilder.security.manager:User info does not have username or email
[2019-05-23 12:52:10,130] ERROR in app: Exception on /oauth-authorized/login [GET]
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1982, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1614, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1517, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1598, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/usr/local/lib/python3.6/site-packages/flask_appbuilder/security/views.py", line 519, in oauth_authorized
resp = self.appbuilder.sm.oauth_remotes[provider].authorized_response()
如果有人对我做错了什么有一些指示,请您帮助我。
【问题讨论】:
【参考方案1】:您应该像文档https://flask-appbuilder.readthedocs.io/en/latest/security.html#authentication-oauth 中那样将注释@appbuilder.sm.oauth_user_info_getter
添加到get_oauth_user_info
函数中
也改变
me = self.appbuilder.sm.oauth_remotes[provider].get("user")
到
me = self.appbuilder.sm.oauth_remotes[provider].get("userinfo")
如果base_url
类似于https://keycloak-domain/auth/realms/realm/protocol/openid-connect/
【讨论】:
我使用了你的部分解决方案,因为我不需要添加装饰器@appbuilder.sm.oauth_user_info_getter
来让我的代码工作。主要问题是我的 base_url 并将“用户”更改为“用户信息”。谢谢。以上是关于如何在 Flask-Appbuilder 中为 OAuth2.0 使用自定义提供程序 [keycloak]?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 AssemblyScript 中为 NEAR 合约创建 UID?