Replies: 5 comments 23 replies
-
@gtg472b Curious if you got Superset integrated with Cognito? |
Beta Was this translation helpful? Give feedback.
-
Can I get token before in CustomSsoAuthOAuthView before logout ?Help me please |
Beta Was this translation helpful? Give feedback.
-
@gtg472b why did you add time.sleep(1) in your custom logout code? |
Beta Was this translation helpful? Give feedback.
-
Hi @gtg472b, thanks for sharing. ➡️ Wondering what you used as the allowed callback url in Cognito? Wanted to use When changing my callback url to Here is my code (very close to what you shared):
from superset.security import SupersetSecurityManager
from flask_appbuilder.security.views import AuthOAuthView
from flask_appbuilder.baseviews import expose
import time
from flask import redirect
import logging
logger = logging.getLogger("CognitoSecurityManager")
class CustomSsoAuthOAuthView(AuthOAuthView):
@expose("/login/")
def login(self, provider="cognito"):
return super().login(provider=provider) #, register = None)
@expose("/logout/")
def logout(self, provider="cognito", register=None):
provider_obj = self.appbuilder.sm.oauth_remotes[provider]
url = ("logout?client_id={}&response_type={}&redirect_uri={}".format(
provider_obj.client_id,
provider_obj.server_metadata.get('response_type'),
provider_obj.server_metadata.get('logout_redirect_uri')
) )
ret = super().logout()
time.sleep(1)
return redirect("{}{}".format( provider_obj.api_base_url, url ) )
class CustomSsoSecurityManager(SupersetSecurityManager):
# override the logout function
authoauthview = CustomSsoAuthOAuthView
def oauth_user_info(self, provider, response=None):
if provider == 'cognito':
res = self.appbuilder.sm.oauth_remotes[provider].get('oauth2/userInfo')
if res.raw.status != 200:
logger.error('Failed to obtain user info: %s', res.data)
return
me = json.loads(res._content)
logger.debug(" user_data: %s", me)
prefix = 'Superset'
return {
# 'username' : me['username'],
# 'name' : me['name'],
'email' : me['email'],
# 'first_name': me['given_name'],
# 'last_name': me['family_name'],
}
COGNITO_URL = "https://qwertyuiop.auth.eu-west-1.amazoncognito.com/"
CLIENT_ID = "1234abcd"
CLIENT_SECRET = "" # I didn't set a secret here
LOGOUT_REDIRECT_URI = "http://localhost:8088/"
OAUTH_PROVIDERS = [{
'name':'cognito',
'token_key': 'access_token',
'icon':'fa-amazon',
'url': COGNITO_URL,
'remote_app': {
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'request_token_params': {
'scope': 'email openid profile'
},
# 'response_type': 'token',
'response_type': 'code',
'base_url': os.path.join(COGNITO_URL, 'oauth2/idpresponse'),
'access_token_url': os.path.join(COGNITO_URL, 'oauth2/token'),
'authorize_url': os.path.join(COGNITO_URL, 'oauth2/authorize'),
'access_token_method':'POST',
'request_token_url': None,
'api_base_url': COGNITO_URL,
'logout_url': os.path.join(COGNITO_URL, 'logout'),
'logout_redirect_uri': LOGOUT_REDIRECT_URI
}
}
]
from custom_sso_security_manager import CustomSsoSecurityManager
CUSTOM_SECURITY_MANAGER = CustomSsoSecurityManager I've also tried without the Any help appreciated. |
Beta Was this translation helpful? Give feedback.
-
This worked for me on Apache/Superset 3.1.0 official Docker image.
from flask_appbuilder.security.manager import AUTH_OAUTH
from superset.security import SupersetSecurityManager
from flask_appbuilder.security.views import AuthOAuthView
from flask_appbuilder.baseviews import expose
from flask import redirect
import logging
import time
class CustomSsoAuthOAuthView(AuthOAuthView):
@expose("/logout/")
def logout(self, provider="cognito", register=None):
ret = super().logout()
time.sleep(1)
return redirect( 'https://xxx.auth.ap-xxx-1.amazoncognito.com/logout?client_id=xxx&logout_uri=https://<your-domain>/login' )
# Create custom SSO to fetch user detail to Superset
class CustomSsoSecurityManager(SupersetSecurityManager):
authoauthview = CustomSsoAuthOAuthView
def oauth_user_info(self, provider, response=None):
# Logic to fetch user info for provider 'cognito'
if provider == 'cognito':
try:
# Make request using OAuth remote to get user information
res = self.appbuilder.sm.oauth_remotes[provider].get('/oauth2/userInfo')
if res.raw.status != 200:
# Log error if user info was not obtained successfully
logging.error('Failed to obtain user info: %s', res.json())
return
me = res.json() # Parse JSON response containing user details
# Return essential user information for Superset
return {
'username' : me['username'],
'name' : me['username'],
'email' : me['email'],
}
except Exception as e:
# Log general exception if something goes wrong
logging.error("CustomSsoSecurityManager: ",e)
CUSTOM_SECURITY_MANAGER = CustomSsoSecurityManager # Use our custom security manager
ENABLE_PROXY_FIX=True # Enables support for reverse proxies like Nginx or Apache
AUTH_TYPE = AUTH_OAUTH # Sets authentication type to OAuth
AUTH_USER_REGISTRATION = True # Enables user self-registration, allowing to create Flask users from Authorized User
AUTH_USER_REGISTRATION_ROLE = "Public" # Sets default role for new users
OAUTH_PROVIDERS = [{
'name' :'cognito', # Name of the OAuth provider
'token_key' :'access_token', # Key where the access token is found in the response
'icon' :'fa-address-card', # Font Awesome icon for the provider
'remote_app': {
'client_id' : 'xxx', # Client Id (Identify Superset application)
'client_secret' : 'xxx', # Secret for this Client Id (Identify Superset application)
'server_metadata_url' : 'https://xxx.ap-xxx-1.amazonaws.com/ap-xxx-1_xxx/.well-known/openid-configuration', # Metadata endpoint of the provider
'api_base_url' : 'https://xxx.auth.ap-xxx-1.amazoncognito.com', # Base URL of the provider
'authorize_url' : 'https://xxx.auth.ap-xxx-1.amazoncognito.com/oauth2/authorize', # Authorization URL
'access_token_url' : 'https://xxx.auth.ap-xxx-1.amazoncognito.com/oauth2/token', # Token endpoint
'client_kwargs' : {'scope': 'openid email'}, # Scopes requested from the provider
},
}] |
Beta Was this translation helpful? Give feedback.
-
This took me long enough to figure out that I figure I'll post what I did so other people can use it if needed. The issue revolves around needing to revoke Cognito's token so that someone can sign out of Superset and then sign in as a different user, rather than having to wait for Cognito's token to just expire.
custom_sso_security_manager.py
The problem was that I needed to override the AuthView logout endpoint to force a request to Cognito's logout endpoint. Import this and set up your OAUTH_PROVIDERS in your main config. I used:
And make sure that in Cognito's dashboard on AWS, you set up your App client settings:
Callback and Sign out URLs
Allowes OAuth Flows (code grant and implicit?)
Beta Was this translation helpful? Give feedback.
All reactions