首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Apache Superset和Auth0返回“意外的关键字参数'scope'”

Apache Superset和Auth0返回“意外的关键字参数'scope'”
EN

Stack Overflow用户
提问于 2021-10-20 11:35:44
回答 3查看 170关注 0票数 0

不久前,我使用AWS Cognito成功地将Superset身份验证与Oauth集成在一起。

现在,我试着用Auth0做同样的事情,重用以前的配置,并根据Auth0文档更改端点。

不幸的是,登录失败,Superset的日志返回以下消息:

2021-10-20 10:30:48,886:ERROR:flask_appbuilder.security.views:Error on OAuth authorize: request() got an unexpected keyword argument 'scope'

这是superset_config.py中的Oauth配置

代码语言:javascript
运行
复制
from superset.security import SupersetSecurityManager

import json
import logging

logger = logging.getLogger(__name__)

class CustomSsoSecurityManager(SupersetSecurityManager):
    def oauth_user_info(self, provider, response=None):
        if provider == 'auth0':
            res = self.appbuilder.sm.oauth_remotes[provider].get('userinfo')
            if res.raw.status != 200:
                logger.error('Failed to obtain user info: %s', res.data)
                return
            me = json.loads(res._content)
            logger.warning(" user_data: %s", me)
            prefix = 'Superset'
            logging.warning("user_data: {0}".format(me))
            return {
                'username' : me['email'],
                'name' : me['name'],
                'email' : me['email'],
                'first_name': me['given_name'],
                'last_name': me['family_name'],
            }

AUTH_TYPE = AUTH_OAUTH
AUTH_USER_REGISTRATION = True
AUTH_USER_REGISTRATION_ROLE = "Public"

AUTH0_URL = os.getenv('AUTH0_URL')
AUTH0_CLIENT_KEY = os.getenv('AUTH0_CLIENT_KEY')
AUTH0_CLIENT_SECRET = os.getenv('AUTH0_CLIENT_SECRET')

OAUTH_PROVIDERS = [{
    'name':'auth0',
    'token_key': 'access_token',
    'icon':'fa-at',
    'url': AUTH0_URL,
    'remote_app': {
        'client_id': AUTH0_CLIENT_KEY,
        'client_secret': AUTH0_CLIENT_SECRET,
        'request_token_params': {
            'scope': 'email openid profile'
        },
        'response_type': 'token_id',
        'base_url': AUTH0_URL,
        'access_token_url': os.path.join(AUTH0_URL, 'oauth/token'),
        'authorize_url': os.path.join(AUTH0_URL, 'authorize'),
        'access_token_method':'POST',
        'request_token_url': os.path.join(AUTH0_URL, 'oauth/token'),
        'api_base_url': AUTH0_URL,
        }
    }
]

CUSTOM_SECURITY_MANAGER = CustomSsoSecurityManager

我已经尝试了不同的代码值( response_type、token、token_id)。

我还尝试将request_token_url保留为空,在这种情况下,由于用户数据看起来是一个空字典,因此错误发生了变化:

代码语言:javascript
运行
复制
2021-10-13 15:52:10,358:WARNING:superset_config: user_data: {}
2021-10-13 15:52:10,358:WARNING:root:user_data: {}
2021-10-13 15:52:10,358:ERROR:flask_appbuilder.security.views:Error returning OAuth user info: 'email'

所以我假设令牌实际上是返回的,我不明白为什么Flask会抱怨属性"scope“。

我也尝试过this,因为它看起来和我的问题非常相似,但这些配置都不适合我。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-10-27 02:55:15

根据Flask Documentation,尝试使用client_kwargs而不是request_token_params密钥。

示例:

代码语言:javascript
运行
复制
{
    'name':'google',
    'icon':'fa-google',
    'token_key':'access_token',
    'remote_app': {
            'client_id':'GOOGLE_KEY',
            'client_secret':'GOOGLE_SECRET',
            'api_base_url':'https://www.googleapis.com/oauth2/v2/',
            'client_kwargs':{
              'scope': 'email profile'
            },
            'request_token_url':None,
            'access_token_url':'https://accounts.google.com/o/oauth2/token',
            'authorize_url':'https://accounts.google.com/o/oauth2/auth'
    }
},
票数 0
EN

Stack Overflow用户

发布于 2021-10-20 17:29:41

我希望你有两个文件作为custom_sso_security_manager.py和superset_config.py

你能从return and try(custom_sso_security_manager.py)中去掉下面两行吗?

代码语言:javascript
运行
复制
'first_name': me['given_name'],
'last_name': me['family_name'],
票数 0
EN

Stack Overflow用户

发布于 2021-10-27 14:38:44

这是为了将来参考,尽管我接受了Kamal的回答。

事实证明,设置请求令牌作用域的正确参数是client_kwargs而不是request_token_params

这是根据Auth0对超集进行身份验证的工作配置:

代码语言:javascript
运行
复制
## Enable OAuth authentication
from flask_appbuilder.security.manager import (
    AUTH_OAUTH,
)

from superset.security import SupersetSecurityManager

import json
import logging
import string
import random

nonce = ''.join(random.choices(string.ascii_uppercase + string.digits + string.ascii_lowercase, k = 30))

logger = logging.getLogger(__name__)

class CustomSsoSecurityManager(SupersetSecurityManager):
    def oauth_user_info(self, provider, response=None):
        if provider == 'auth0':
            res = self.appbuilder.sm.oauth_remotes[provider].get('userinfo')
            if res.raw.status != 200:
                logger.error('Failed to obtain user info: %s', res.json())
                return
            me = res.json()
            return {
                'username' : me['email'],
                'name' : me['name'],
                'email' : me['email'],
            }

AUTH_TYPE = AUTH_OAUTH
AUTH_USER_REGISTRATION = True
AUTH_USER_REGISTRATION_ROLE = "Public"

AUTH0_URL = os.getenv('AUTH0_URL')
AUTH0_CLIENT_KEY = os.getenv('AUTH0_CLIENT_KEY')
AUTH0_CLIENT_SECRET = os.getenv('AUTH0_CLIENT_SECRET')

OAUTH_PROVIDERS = [
  {   'name':'auth0',
      'token_key':'access_token',
      'icon':'fa-at',
      'remote_app': {
          'api_base_url': AUTH0_URL,
          'client_id': AUTH0_CLIENT_KEY,  
          'client_secret': AUTH0_CLIENT_SECRET, 
          'server_metadata_url': os.path.join(AUTH0_URL, '.well-known/openid-configuration'),
          'client_kwargs': {
              'scope': 'openid profile email'
          },
         'response_type': 'code token',
         'nonce': nonce,
      }
  }
]

CUSTOM_SECURITY_MANAGER = CustomSsoSecurityManager
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69645248

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档