bito-code-review[bot] commented on code in PR #38092:
URL: https://github.com/apache/superset/pull/38092#discussion_r2827000469
##########
docs/docs/installation/kubernetes.mdx:
##########
@@ -308,6 +308,121 @@ configOverrides:
AUTH_USER_REGISTRATION_ROLE = "Admin"
```
+:::note
+
+Here another example with groups mapping, logout from Keycloak and PKCE flow.
+You need to create a Secret that contains CLIENT_ID, CLIENT_SECRET and
OIDC_ISSUER.
+
+Your oauth provider must be configured to support PKCE flow.
+For keycloak for example, you need to set 'Proof Key for Code Exchange Code
Challenge Method' to value S256 under:
+Clients -> <your-client-id> -> Advanced -> Advanced settings
+
+:::
+
+```yaml
+extraSecretEnv:
+ CLIENT_ID: my_superset_clientid
+ CLIENT_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ OIDC_ISSUER: https://myoauthprovider.youpi.fr/auth/realms/MYREALM
+
+configOverrides:
+ enable_oauth: |
+ from flask import redirect, request, session
+ from flask_appbuilder import expose
+ from flask_appbuilder.security.manager import AUTH_OAUTH
+ from flask_appbuilder.security.views import AuthOAuthView
+ from superset.security import SupersetSecurityManager
+ import logging
+ import os
+ import requests
+
+ log = logging.getLogger(__name__)
+
+ AUTH_TYPE = AUTH_OAUTH
+ AUTH_USER_REGISTRATION = True
+ AUTH_ROLES_SYNC_AT_LOGIN = True
+ AUTH_USER_REGISTRATION_ROLE = 'Public'
+
+ PROVIDER_NAME = 'keycloak'
+ CLIENT_ID = os.getenv('CLIENT_ID')
+ CLIENT_SECRET = os.getenv('CLIENT_SECRET')
+ OIDC_ISSUER = os.getenv('OIDC_ISSUER')
+ OIDC_BASE_URL = f'{OIDC_ISSUER}/protocol/openid-connect'
+ OIDC_AUTH_URL = f'{OIDC_BASE_URL}/auth'
+ OIDC_METADATA_URL = f'{OIDC_ISSUER}/.well-known/openid-configuration'
+ OIDC_TOKEN_URL = f'{OIDC_BASE_URL}/token'
+ OIDC_USERINFO_URL = f'{OIDC_BASE_URL}/userinfo'
+ OAUTH_PROVIDERS = [
+ {
+ 'name': PROVIDER_NAME,
+ 'token_key': 'access_token',
+ 'icon': 'fa-circle-o',
+ 'remote_app': {
+ 'api_base_url': OIDC_BASE_URL,
+ 'access_token_url': OIDC_TOKEN_URL,
+ 'authorize_url': OIDC_AUTH_URL,
+ 'request_token_url': None,
+ 'server_metadata_url': OIDC_METADATA_URL,
+ 'client_id': CLIENT_ID,
+ 'client_secret': CLIENT_SECRET,
+ 'client_kwargs': {
+ 'scope': 'openid email profile',
+ 'code_challenge_method': 'S256',
+ 'response_type': 'code',
+ },
+ },
+ }
+ ]
+
+ # Make sure you create these groups on Keycloak
+ AUTH_ROLES_MAPPING = {
+ f'{CLIENT_ID}_admin': ['Admin'],
+ f'{CLIENT_ID}_alpha': ['Alpha'],
+ f'{CLIENT_ID}_gamma': ['Gamma'],
+ f'{CLIENT_ID}_public': ['Public'],
+ }
+
+
+ # Custom OAuth view to handle logout redirection to Keycloak
+ class CustomOAuthView(AuthOAuthView):
+ @expose('/logout/', methods=['GET', 'POST'])
+ def logout(self):
+ session.clear()
+ return redirect(
+
f'{OIDC_ISSUER}/protocol/openid-connect/logout?post_logout_redirect_uri={request.url_root.strip("/")}&client_id={CLIENT_ID}'
+ )
+
+
+ class CustomSsoSecurityManager(SupersetSecurityManager):
+ # Override the default OAuth view with our custom one
+ authoauthview = CustomOAuthView
+
+ # Override the method to fetch groups from the token and map them to
Superset roles
+ def get_oauth_user_info(self, provider, response):
+ if provider == 'keycloak':
+ headers = {'Authorization': f"Bearer
{response['access_token']}"}
+ resp = requests.get(OIDC_USERINFO_URL, headers=headers,
timeout=5)
+
+ log.info(f'userinfo: {me}')
+
+ groups = me.get('groups', [])
+ if not groups:
+ groups = ['Public']
+
+ return {
+ 'username': me.get('preferred_username'),
+ 'email': me.get('email'),
+ 'first_name': me.get('given_name'),
+ 'last_name': me.get('family_name'),
+ 'role_keys': groups,
+ }
+ return {}
+
+ # Set our custom security manager
+ CUSTOM_SECURITY_MANAGER = CustomSsoSecurityManager
+```
+
Review Comment:
<div>
<div id="suggestion">
<div id="issue"><b>Incorrect OAuth role mapping</b></div>
<div id="fix">
The role_keys assignment in get_oauth_user_info does not match the
AUTH_ROLES_MAPPING keys. The mapping uses prefixed keys like
f'{CLIENT_ID}_admin', but role_keys is set to raw groups. This will prevent
proper role assignment. Also, the default groups fallback uses 'Public' which
doesn't correspond to any mapping key.
</div>
</div>
<small><i>Code Review Run #c52ec5</i></small>
</div><div>
<div id="suggestion">
<div id="issue"><b>Runtime error: undefined variable</b></div>
<div id="fix">
The variable 'me' is referenced throughout the method but never defined,
which will cause a NameError at runtime when this OAuth path is executed. This
appears to be an oversight in the documentation code example.
</div>
<details>
<summary>
<b>Code suggestion</b>
</summary>
<blockquote>Check the AI-generated fix before applying</blockquote>
<div id="code">
```
- resp = requests.get(OIDC_USERINFO_URL, headers=headers, timeout=5)
- log.info(f'userinfo: {me}')
+ resp = requests.get(OIDC_USERINFO_URL, headers=headers, timeout=5)
+ me = resp.json()
+ log.debug(f'Received userinfo from OIDC provider for user
{me.get(\"preferred_username\")}')
```
</div>
</details>
</div>
<small><i>Code Review Run #ae1161</i></small>
</div>
---
Should Bito avoid suggestions like this for future reviews? (<a
href=https://alpha.bito.ai/home/ai-agents/review-rules>Manage Rules</a>)
- [ ] Yes, avoid them
--
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: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]