首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Apache SuperSet中的SuperSet代码认证--而不是密钥披风

Apache SuperSet中的SuperSet代码认证--而不是密钥披风
EN

Stack Overflow用户
提问于 2021-05-18 13:35:00
回答 1查看 1.2K关注 0票数 1

我一直试图为OpenID设置SuperSet身份验证。我见过许多Oauth的配置,但OpenID没有。

我尝试了以下配置:

代码语言:javascript
复制
from formshare_sso_security_manager import FormShareSsoSecurityManager
from flask_appbuilder.security.manager import AUTH_OID
...
AUTH_TYPE = AUTH_OID


OPENID_PROVIDERS = [
    {
        'name': 'FormShare',
        'icon': 'fa-google',
        'token_key': 'access_token',
        'remote_app': {
            'client_id': '501cE2ow7V4J',
            'client_secret': '060a450db0474b7db20afeda22a671b6',
            'api_base_url': 'https://qlands.ngrok.io/',
            'client_kwargs':{
              'scope': 'profile'
            },
            'request_token_url': None,
            'access_token_url': 'https://qlands.ngrok.io/openid_token',
            'authorize_url': 'https://qlands.ngrok.io/openid_authentication'
        }
    }
]

formshare_sso_security_manager.py的内容如下:

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

class FormShareSsoSecurityManager(SupersetSecurityManager):
    def oauth_user_info(self, provider, response=None):
        logging.debug("Oauth2 provider: {0}.".format(provider))
        if provider == 'FormShare':
            me = self.appbuilder.sm.oauth_remotes[provider].get('openid_userinfo').data
            logging.debug("user_data: {0}".format(me))
            return { 'name' : me['name'], 'email' : me['email'], 'id' : me['user_name'], 'username' : me['user_name'], 'first_name':'', 'last_name':''} 

但是,我在Superset登录中获得了以下图像:

如果我单击提供程序,什么都不会发生,但是接口会向我请求输入我的OpenID ID。如果我输入一个经过身份验证的用户id,例如"carlos“Superset日志:

代码语言:javascript
复制
"GET /login/?next=http://qlands.eu.ngrok.io/login/ HTTP/1.1" 200 -
2021-05-18 09:53:17,871:WARNING:superset.views.base:404 Not Found: The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.

我想我的配置是基于OAuth的,但是OpenID是不同的吗?我在keycloak上看到了一篇文章,但是我的OpenID服务器是一个简单的实现,它使用了用https://oidcdebugger.com/测试的PyOp

我希望超级集执行GET to 身份验证来对用户进行身份验证,作为回报,服务器将提供一个代码,用于将其交换为令牌,并使用该令牌获取用户信息。

我还尝试了以下OAUTH配置,该配置使我在身份验证过程中前进了一步:

代码语言:javascript
复制
OAUTH_PROVIDERS = [
    {   'name':'FormShare',
        'token_key':'access_token', # Name of the token in the response of access_token_url
        'icon':'fa-address-card',   # Icon for the provider
        'remote_app': {
            'client_id':'501cE2ow7V4J',  # Client Id (Identify Superset application)
            'client_secret':'060a450db0474b7db20afeda22a671b6', # Secret for this Client Id (Identify Superset application)
            'client_kwargs':{
                'scope': 'openid profile'               # Scope for the Authorization
            },
            'access_token_method':'POST',    # HTTP Method to call access_token_url
            'access_token_params':{},
            'access_token_headers':{    # Additional headers for calls to access_token_url
                'Authorization': 'Basic Base64EncodedClientIdAndSecret'
            },
            'base_url':'https://qlands.ngrok.io',
            'access_token_url':'https://qlands.ngrok.io/openid_token',
            'authorize_url':'https://qlands.ngrok.io/openid_authentication'
        }
    }
]

Superset提供了以下输出:

代码语言:javascript
复制
2021-05-19 15:08:29,869:DEBUG:authlib.integrations.base_client.base_app:Saving authorize data: {'redirect_uri': 'http://qlands.eu.ngrok.io/oauth-authorized/FormShare', 'nonce': 'V3k0XaaVFL6pBqGbjGNt', 'url': 'https://qlands.ngrok.io/openid_authentication?response_type=code&client_id=501cE2ow7V4J&redirect_uri=http%3A%2F%2Fqlands.eu.ngrok.io%2Foauth-authorized%2FFormShare&scope=openid+profile&state=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuZXh0IjpbIiJdfQ.NTWe_SlU7cdUrf4WrQFRxasVKdcIpm98sMOoXkMg2No&nonce=V3k0XaaVFL6pBqGbjGNt', 'state': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuZXh0IjpbIiJdfQ.NTWe_SlU7cdUrf4WrQFRxasVKdcIpm98sMOoXkMg2No'}
2021-05-19 15:08:29,872:INFO:werkzeug:127.0.0.1 - - [19/May/2021 15:08:29] "GET /login/FormShare?next= HTTP/1.1" 302 -
2021-05-19 15:08:30,636:DEBUG:authlib.integrations.base_client.base_app:Retrieve temporary data: {'code': '89cb4c27ed4f42268c59ab170a932aa1', 'state': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuZXh0IjpbIiJdfQ.NTWe_SlU7cdUrf4WrQFRxasVKdcIpm98sMOoXkMg2No', 'redirect_uri': 'http://qlands.eu.ngrok.io/oauth-authorized/FormShare'}
2021-05-19 15:08:30,641:DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): qlands.ngrok.io:443
2021-05-19 15:08:30,929:DEBUG:urllib3.connectionpool:https://qlands.ngrok.io:443 "POST /openid_token HTTP/1.1" 200 1140
Oauth2 provider: FormShare.
2021-05-19 15:08:30,938:INFO:werkzeug:127.0.0.1 - - [19/May/2021 15:08:30] "GET /oauth-authorized/FormShare?code=89cb4c27ed4f42268c59ab170a932aa1&state=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuZXh0IjpbIiJdfQ.NTWe_SlU7cdUrf4WrQFRxasVKdcIpm98sMOoXkMg2No HTTP/1.1" 302 -
2021-05-19 15:08:31,310:INFO:werkzeug:127.0.0.1 - - [19/May/2021 15:08:31] "GET /login/ HTTP/1.1" 200 -

使用Superset发出的下列请求

代码语言:javascript
复制
[3]GET /login/                     200 OK                                                                                                                        
[2]GET /oauth-authorized/FormShare 302 FOUND                                                                                                                     
[1]GET /login/FormShare            302 FOUND  

以及Supeset向OpenID服务器提出的以下请求:

代码语言:javascript
复制
[2]POST /openid_token             200 OK                                                                                                                         
[1]GET  /openid_authentication    303 See Other

但是,这个过程又带我用消息登录:

无效登录。请再试一次。

如有任何提示,我们将不胜感激

EN

回答 1

Stack Overflow用户

发布于 2021-05-21 14:07:28

经过一些尝试和错误之后,我设法用我的OpenID服务器配置了OpenID,但是使用了OAUTH。我使用了以下配置:

代码语言:javascript
复制
from formshare_sso_security_manager import FormShareSsoSecurityManager
from flask_appbuilder.security.manager import AUTH_OAUTH
...
CUSTOM_SECURITY_MANAGER = FormShareSsoSecurityManager
AUTH_TYPE = AUTH_OAUTH


OAUTH_PROVIDERS = [
    {
        "name": "FormShare",
        "token_key": "access_token",  # Name of the token in the response of access_token_url
        "icon": "fa-address-card",  # Icon for the provider
        "remote_app": {
            "client_id": "501cE2ow7V4J",  # Client Id (Identify Superset application)
            "client_secret": "060a450db0474b7db20afeda22a671b6",  # Secret for this Client Id (Identify Superset application)
            "client_kwargs": {"scope": "openid profile"},  # Scope for the Authorization
            "access_token_method": "POST",  # HTTP Method to call access_token_url
            "access_token_params": {
                "redirect_uri": "http://qlands.eu.ngrok.io/oauth-authorized/FormShare"
            },
            "access_token_headers": {  # Additional headers for calls to access_token_url
                "Authorization": "Basic Base64EncodedClientIdAndSecret"
            },
            "base_url": "https://qlands.ngrok.io",
            "access_token_url": "https://qlands.ngrok.io/openid_token",
            "authorize_url": "https://qlands.ngrok.io/openid_authentication",
        },
    }
]

自定义管理器代码是:

代码语言:javascript
复制
class FormShareSsoSecurityManager(SupersetSecurityManager):
    def oauth_user_info(self, provider, response=None):
        if provider == "FormShare":
            access_token = response["access_token"]
            headers = {"Authorization": "Bearer {}".format(access_token)}
            response = requests.get("https://qlands.ngrok.io/openid_userinfo", headers=headers)
            user_data = response.json()
            return {
                "name": user_data["name"],
                "email": user_data["email"],
                "id": user_data["user_name"],
                "username": user_data["user_name"],
                "first_name": user_data["name"],
                "last_name": user_data["name"],
            }

自定义安全管理器使用Python请求获取用户信息,因为超集文档中指示的以下代码无法工作:

代码语言:javascript
复制
me = self.appbuilder.sm.oauth_remotes[provider].get('openid_userinfo').data

要使OpenID集成工作,您需要在superset_config.py文件中设置AUTH_USER_REGISTRATION = True,这对OpenID没有意义。因此,如果您有AUTH_USER_REGISTRATION = False,则需要修改管理器以自定义函数auth_user_oauth():

代码语言:javascript
复制
class FormShareSsoSecurityManager(SupersetSecurityManager):
    def oauth_user_info(self, provider, response=None):
        if provider == "FormShare":
            access_token = response["access_token"]
            headers = {"Authorization": "Bearer {}".format(access_token)}
            response = requests.get("https://qlands.ngrok.io/openid_userinfo", headers=headers)
            user_data = response.json()
            return {
                "name": user_data["name"],
                "email": user_data["email"],
                "id": user_data["user_name"],
                "username": user_data["user_name"],
                "first_name": user_data["name"],
                "last_name": user_data["name"],
            }

    def auth_user_oauth(self, userinfo):
        ...

flask_appbuilder/security/manager.py的原始用户一样,但是要自动注册,用户一次由OpenID客户端进行身份验证。

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

https://stackoverflow.com/questions/67587338

复制
相关文章

相似问题

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