docs: Added Keycloak auth configuration (#29487)
Co-authored-by: Sam Firke <sfirke@users.noreply.github.com>
This commit is contained in:
parent
d535f3fe56
commit
3f6b7e2456
|
|
@ -321,7 +321,103 @@ CUSTOM_SECURITY_MANAGER = CustomSsoSecurityManager
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
### Keycloak-Specific Configuration using Flask-OIDC
|
||||||
|
If you are using Keycloak as OpenID Connect 1.0 Provider, the above configuration based on [`Authlib`](https://authlib.org/) might not work. In this case using [`Flask-OIDC`](https://https://pypi.org/project/flask-oidc/) is a viable option.
|
||||||
|
|
||||||
|
Make sure the pip package [`Flask-OIDC`](https://https://pypi.org/project/flask-oidc/) is installed on the webserver. This was succesfully tested using version 2.2.0. This package requires [`Flask-OpenID`](https://pypi.org/project/Flask-OpenID/) as a dependency.
|
||||||
|
|
||||||
|
The following code defines a new security manager. Add it to a new file named `keycloak_security_manager.py`, placed in the same directory as your `superset_config.py` file.
|
||||||
|
```python
|
||||||
|
from flask_appbuilder.security.manager import AUTH_OID
|
||||||
|
from superset.security import SupersetSecurityManager
|
||||||
|
from flask_oidc import OpenIDConnect
|
||||||
|
from flask_appbuilder.security.views import AuthOIDView
|
||||||
|
from flask_login import login_user
|
||||||
|
from urllib.parse import quote
|
||||||
|
from flask_appbuilder.views import ModelView, SimpleFormView, expose
|
||||||
|
from flask import (
|
||||||
|
redirect,
|
||||||
|
request
|
||||||
|
)
|
||||||
|
import logging
|
||||||
|
|
||||||
|
class OIDCSecurityManager(SupersetSecurityManager):
|
||||||
|
|
||||||
|
def __init__(self, appbuilder):
|
||||||
|
super(OIDCSecurityManager, self).__init__(appbuilder)
|
||||||
|
if self.auth_type == AUTH_OID:
|
||||||
|
self.oid = OpenIDConnect(self.appbuilder.get_app)
|
||||||
|
self.authoidview = AuthOIDCView
|
||||||
|
|
||||||
|
class AuthOIDCView(AuthOIDView):
|
||||||
|
|
||||||
|
@expose('/login/', methods=['GET', 'POST'])
|
||||||
|
def login(self, flag=True):
|
||||||
|
sm = self.appbuilder.sm
|
||||||
|
oidc = sm.oid
|
||||||
|
|
||||||
|
@self.appbuilder.sm.oid.require_login
|
||||||
|
def handle_login():
|
||||||
|
user = sm.auth_user_oid(oidc.user_getfield('email'))
|
||||||
|
|
||||||
|
if user is None:
|
||||||
|
info = oidc.user_getinfo(['preferred_username', 'given_name', 'family_name', 'email'])
|
||||||
|
user = sm.add_user(info.get('preferred_username'), info.get('given_name'), info.get('family_name'),
|
||||||
|
info.get('email'), sm.find_role('Gamma'))
|
||||||
|
|
||||||
|
login_user(user, remember=False)
|
||||||
|
return redirect(self.appbuilder.get_url_for_index)
|
||||||
|
|
||||||
|
return handle_login()
|
||||||
|
|
||||||
|
@expose('/logout/', methods=['GET', 'POST'])
|
||||||
|
def logout(self):
|
||||||
|
oidc = self.appbuilder.sm.oid
|
||||||
|
|
||||||
|
oidc.logout()
|
||||||
|
super(AuthOIDCView, self).logout()
|
||||||
|
redirect_url = request.url_root.strip('/') + self.appbuilder.get_url_for_login
|
||||||
|
|
||||||
|
return redirect(
|
||||||
|
oidc.client_secrets.get('issuer') + '/protocol/openid-connect/logout?redirect_uri=' + quote(redirect_url))
|
||||||
|
```
|
||||||
|
Then add to your `superset_config.py` file:
|
||||||
|
```python
|
||||||
|
from keycloak_security_manager import OIDCSecurityManager
|
||||||
|
from flask_appbuilder.security.manager import AUTH_OID, AUTH_REMOTE_USER, AUTH_DB, AUTH_LDAP, AUTH_OAUTH
|
||||||
|
import os
|
||||||
|
|
||||||
|
AUTH_TYPE = AUTH_OID
|
||||||
|
SECRET_KEY: 'SomethingNotEntirelySecret'
|
||||||
|
OIDC_CLIENT_SECRETS = '/path/to/client_secret.json'
|
||||||
|
OIDC_ID_TOKEN_COOKIE_SECURE = False
|
||||||
|
OIDC_OPENID_REALM: '<myRealm>'
|
||||||
|
OIDC_INTROSPECTION_AUTH_METHOD: 'client_secret_post'
|
||||||
|
CUSTOM_SECURITY_MANAGER = OIDCSecurityManager
|
||||||
|
|
||||||
|
# Will allow user self registration, allowing to create Flask users from Authorized User
|
||||||
|
AUTH_USER_REGISTRATION = True
|
||||||
|
|
||||||
|
# The default user self registration role
|
||||||
|
AUTH_USER_REGISTRATION_ROLE = 'Public'
|
||||||
|
```
|
||||||
|
Store your client-specific OpenID information in a file called `client_secret.json`. Create this file in the same directory as `superset_config.py`:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"<myOpenIDProvider>": {
|
||||||
|
"issuer": "https://<myKeycloakDomain>/realms/<myRealm>",
|
||||||
|
"auth_uri": "https://<myKeycloakDomain>/realms/<myRealm>/protocol/openid-connect/auth",
|
||||||
|
"client_id": "https://<myKeycloakDomain>",
|
||||||
|
"client_secret": "<myClientSecret>",
|
||||||
|
"redirect_uris": [
|
||||||
|
"https://<SupersetWebserver>/oauth-authorized/<myOpenIDProvider>"
|
||||||
|
],
|
||||||
|
"userinfo_uri": "https://<myKeycloakDomain>/realms/<myRealm>/protocol/openid-connect/userinfo",
|
||||||
|
"token_uri": "https://<myKeycloakDomain>/realms/<myRealm>/protocol/openid-connect/token",
|
||||||
|
"token_introspection_uri": "https://<myKeycloakDomain>/realms/<myRealm>/protocol/openid-connect/token/introspect"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
## LDAP Authentication
|
## LDAP Authentication
|
||||||
|
|
||||||
FAB supports authenticating user credentials against an LDAP server.
|
FAB supports authenticating user credentials against an LDAP server.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue