You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@superset.apache.org by GitBox <gi...@apache.org> on 2022/04/04 10:19:33 UTC
[GitHub] [superset] nigzak opened a new issue, #19510: OAuth Login: user details are not synchronized, only the entitlements are synced on login
nigzak opened a new issue, #19510:
URL: https://github.com/apache/superset/issues/19510
I have enabled the OIDC login
I have enabled the userinfo endpoint
I have activated the synchronized for the entitlements (AUTH_ROLES_SYNC_AT_LOGIN = True)
#### How to reproduce the bug
1. Login as Admin
2. Navigate to some user and overwrite full name or email and SAVE
3. let the user login with his account via OIDC
4. the overwritten details are still persist and not updated
### Expected results
Similar to the entitlements the user details should be updated from OIDC (if available)
HINT: could be an expected result - but in this case probably an additional feature flag could be added? (like AUTH_USER_SYNC_AT_LOGIN)
### Actual results
User details (except entitlements) are not udpated
### Environment
- browser type: CHROME
- superset version: 1.4.1 Docker Image with AuthLib 0.x
### Checklist
Make sure to follow these steps before submitting your issue - thank you!
- [x] I have checked the superset logs for python stacktraces and included it here as text if there are any.
- [x] I have reproduced the issue with at least the latest released version of superset. => with 1.4.1 (latest stable)
- [x] I have checked the issue tracker for the same issue and I haven't found one similar.
### superset_config.py
```
from flask_appbuilder.security.manager import AUTH_OID,AUTH_REMOTE_USER,AUTH_DB, AUTH_LDAP, AUTH_OAUTH
import os
from custom_sso_security_manager import CustomSsoSecurityManager
CUSTOM_SECURITY_MANAGER = CustomSsoSecurityManager
basedir = os.path.abspath(os.path.dirname(__file__))
SUPERSET_WORKERS = 4
# CRYPTION STUFF -----------------------------------------------------------------------------------
SECRET_KEY = os.getenv('SUPERSET_SECRET_KEY')
# DATABASE STUFF -----------------------------------------------------------------------------------
PSQLHOST=os.getenv('PSQL_HOST')
PSQLPORT=os.getenv('PSQL_PORT')
PSQLUSER=os.getenv('PSQL_USER')
PSQLPASS=os.getenv('PSQL_PASS')
PSQLDB=os.getenv('PSQL_DB')
PSQLSSLMODE = os.getenv('PSQL_SSL_MODE')
PSQLSSLROOTCA = os.getenv('PSQL_SSL_ROOTCA')
print (' USING DB FOR SQLALCHEMY ')
print ('HOST: ' + str(PSQLHOST))
print ('PORT: ' + str(PSQLPORT))
print ('SSL_MODE: ' + PSQLSSLMODE)
print ('SSL_CA: ' + PSQLSSLROOTCA)
if PSQLSSLMODE != None and PSQLSSLMODE != "" and PSQLSSLROOTCA != None and PSQLSSLROOTCA != "":
print('PSQL: SSL MODE USED MODE=' + PSQLSSLMODE + ' CA=' + PSQLSSLROOTCA)
SQLALCHEMY_DATABASE_URI = 'postgresql+psycopg2://' + PSQLUSER + ':' + PSQLPASS + '@' + PSQLHOST + ':' + str(PSQLPORT) + '/' + PSQLDB + '?sslmode=' + PSQLSSLMODE + '&sslrootcert=' + PSQLSSLROOTCA # PSQL must be parsed to STR, otherwise concatenation fails (INT vs STR)
else:
print('PSQL: NO SSL MODE USED')
SQLALCHEMY_DATABASE_URI = 'postgresql+psycopg2://' + PSQLUSER + ':' + PSQLPASS + '@' + PSQLHOST + ':' + str(PSQLPORT) + '/' + PSQLDB
# AUTHENTIFICATION STUFF ---------------------------------------------------------------------------
OIDCCID=os.getenv('OIDC_CLIENT_ID')
OIDCCS=os.getenv('OIDC_CLIENT_SECRET')
CSRF_ENABLED = True
AUTH_TYPE = AUTH_OAUTH
AUTH_USER_REGISTRATION = False
AUTH_ROLES_MAPPING = {
"X.Y": ["test"],
"x.z": ["Admin"]
}
AUTH_ROLES_SYNC_AT_LOGIN = True
PERMANENT_SESSION_LIFETIME = 600
OAUTH_PROVIDERS = [
{
'name': 'XX',
'icon': 'XX',
'token_key': 'access_token',
'remote_app': {
'client_id': OIDCCID,
'client_secret': OIDCCS,
'api_base_url': 'https://sso.xx.com/as/',
'client_kwargs':{
'scope': 'openid email profile authorization_group entitlement_group scoped_entitlement offline_access'
},
'request_token_url': None,
'access_token_url': 'https://sso.xx.com/as/token.oauth2',
'refresh_token_url' : 'https://sso.xx.com/as/token.oauth2',
'authorize_url': 'https://sso.xx.com/as/authorization.oauth2',
'code_challenge_method':'S256',
}
}
]
ENABLE_PROXY_FIX = True
PREFERRED_URL_SCHEME = 'https'
```
### custom_sso_security_manager.py
```
from superset.security import SupersetSecurityManager
import logging
class CustomSsoSecurityManager(SupersetSecurityManager):
def oauth_user_info(self, provider, response=None):
access_token = response["access_token"]
headers = {'Authorization': 'Bearer %s' % (access_token)}
me = self.appbuilder.sm.oauth_remotes[provider].get("https://sso.xx.com/idp/userinfo.openid", headers=headers)
data = me.json()
logging.debug("User info from xx: %s", data)
logging.debug("Entitlements: %s", data.get("entitlement_group", []))
return {
"username": data.get("sub", ""),
"first_name": data.get("given_name", ""),
"last_name": data.get("family_name", ""),
"email": data.get("email", ""),
"role_keys": data.get("entitlement_group", []),
}
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
[GitHub] [superset] nigzak closed issue #19510: OAuth Login: user details are not synchronized, only the entitlements are synced on login
Posted by GitBox <gi...@apache.org>.
nigzak closed issue #19510: OAuth Login: user details are not synchronized, only the entitlements are synced on login
URL: https://github.com/apache/superset/issues/19510
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
[GitHub] [superset] nigzak commented on issue #19510: OAuth Login: user details are not synchronized, only the entitlements are synced on login
Posted by GitBox <gi...@apache.org>.
nigzak commented on issue #19510:
URL: https://github.com/apache/superset/issues/19510#issuecomment-1195459638
found a solution for this: overwrite in custom_sso_security_manager.py required
in addition this code has a modification for add_user (only adding an user if ANY relevant entitlement is available)
in this example code the user must have ANY role which contains "MY_ROLE" (refer matcher variable) to be added
user is known => sync userdetails (+email + username)
user is not known
a) has relevant entitlement => add him
b) has no relevant entitlement => no adding
```
def auth_user_oauth(self, userinfo):
logging.debug('calling auth_user_oauth')
try:
# CLONED ORIGIN FROM https://flask-appbuilder.readthedocs.io/en/latest/_modules/flask_appbuilder/security/manager.html
if "username" in userinfo:
username = userinfo["username"]
elif "email" in userinfo:
username = userinfo["email"]
else:
log.error(
"OAUTH userinfo does not have username or email {0}".format(userinfo)
)
return None
# If username is empty, go away
if (username is None) or username == "":
return None
# Search the DB for this user
user = self.find_user(username=username)
log.debug(user)
# If user is not active, go away
if user and (not user.is_active):
return None
# If user is not registered, and not self-registration, go away
if (not user) and (not self.auth_user_registration):
return None
# Sync the user's roles
if user and self.auth_roles_sync_at_login:
user.roles = self._oauth_calculate_user_roles(userinfo)
log.debug(
"Calculated new roles for user='{0}' as: {1}".format(
username, user.roles
)
)
rolecheck = userinfo.get("role_keys")
matcher = "MY_ROLE"
# If the user is new, register them
if (not user) and self.auth_user_registration:
## MANUAL ADDED: add user only if relevant entitlement_group
if (rolecheck is None):
return # no role
addAllowed = False
for r in rolecheck:
if matcher in r:
addAllowed = True
log.debug("adding allowed because of %s", r)
log.debug(addAllowed)
if (addAllowed):
user = self.add_user(
username=username,
first_name=userinfo.get("first_name", ""),
last_name=userinfo.get("last_name", ""),
email=userinfo.get("email", "") or f"{username}@email.notfound",
role=self._oauth_calculate_user_roles(userinfo),
)
log.debug("New user registered: {0}".format(user))
# If user registration failed, go away
if not user:
log.error("Error creating a new OAuth user {0}".format(username))
return None
else: ## MANUAL ADDED: sync data if already registered
logging.debug("SYNCING USER")
user.first_name = userinfo.get("first_name") ## MANUAL ADDED: sync data
user.last_name = userinfo.get("last_name") ## MANUAL ADDED: sync data
user.email = userinfo.get("email") ## MANUAL ADDED: sync data
# LOGIN SUCCESS (only if user is now registered)
if user:
self.update_user_auth_stat(user)
return user
else:
return None
except ValueError as err:
logging.debug("ERROR CSOM")
logging.debug(err)
logging.debug(err.args)
raise
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org