Skip to content

Commit

Permalink
implement role binding from: AUTH_LDAP, AUTH_OAUTH
Browse files Browse the repository at this point in the history
  • Loading branch information
thesuperzapper committed May 20, 2020
1 parent 0e7f624 commit f73929d
Show file tree
Hide file tree
Showing 5 changed files with 306 additions and 76 deletions.
29 changes: 29 additions & 0 deletions docs/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ Use config.py to configure the following parameters. By default it will use SQLL
| | exist. Mandatory when using user | |
| | registration | |
+----------------------------------------+--------------------------------------------+-----------+
| AUTH_ROLES_SYNC_AT_LOGIN | Sets if user's roles are replaced each | No |
| | login with those received from LDAP/OAUTH | |
| | Default: False | |
+----------------------------------------+--------------------------------------------+-----------+
| AUTH_ROLES_MAPPING | A mapping from LDAP/OAUTH group names | No |
| | to FAB roles | |
| | | |
+----------------------------------------+--------------------------------------------+-----------+
| AUTH_LDAP_SERVER | define your ldap server when AUTH_TYPE=2 | Cond. |
| | example: | |
| | | |
Expand Down Expand Up @@ -96,6 +104,27 @@ Use config.py to configure the following parameters. By default it will use SQLL
| | | |
| | AUTH_LDAP_UID_FIELD = "uid" | |
+----------------------------------------+--------------------------------------------+-----------+
| AUTH_LDAP_GROUP_FIELD | sets the field in the ldap directory that | No |
| | stores the user's group uids. This field | |
| | is used in combination with | |
| | AUTH_ROLES_MAPPING to propagate the users | |
| | groups into the User database. | |
| | Default is "memberOf". | |
| | example: | |
| | | |
| | AUTH_TYPE = 2 | |
| | | |
| | AUTH_LDAP_SERVER = "ldap://ldapserver.new" | |
| | | |
| | AUTH_LDAP_SEARCH = "ou=people,dc=example" | |
| | | |
| | AUTH_LDAP_GROUP_FIELD = "memberOf" | |
| | | |
| | AUTH_ROLES_MAPPING = { | |
| | "cn=User,ou=groups,dc=example,dc=com": | |
| | "User" | |
| | } | |
+----------------------------------------+--------------------------------------------+-----------+
| AUTH_LDAP_FIRSTNAME_FIELD | sets the field in the ldap directory that | No |
| | stores the user's first name. This field | |
| | is used to propagate user's first name | |
Expand Down
115 changes: 104 additions & 11 deletions docs/security.rst
Original file line number Diff line number Diff line change
Expand Up @@ -466,16 +466,22 @@ key is just the configuration for flask-oauthlib::
AUTH_TYPE = AUTH_OAUTH
OAUTH_PROVIDERS = [
{'name':'twitter', 'icon':'fa-twitter',
'remote_app': {
'consumer_key':'TWITTER KEY',
'consumer_secret':'TWITTER SECRET',
'base_url':'https://api.twitter.com/1.1/',
'request_token_url':'https://api.twitter.com/oauth/request_token',
'access_token_url':'https://api.twitter.com/oauth/access_token',
'authorize_url':'https://api.twitter.com/oauth/authenticate'}
{
'name':'twitter',
'icon':'fa-twitter',
'remote_app': {
'consumer_key':'TWITTER KEY',
'consumer_secret':'TWITTER SECRET',
'base_url':'https://api.twitter.com/1.1/',
'request_token_url':'https://api.twitter.com/oauth/request_token',
'access_token_url':'https://api.twitter.com/oauth/access_token',
'authorize_url':'https://api.twitter.com/oauth/authenticate'
}
},
{'name':'google', 'icon':'fa-google', 'token_key':'access_token',
{
'name':'google',
'icon':'fa-google',
'token_key':'access_token',
'remote_app': {
'consumer_key':'GOOGLE KEY',
'consumer_secret':'GOOGLE SECRET',
Expand All @@ -486,14 +492,29 @@ key is just the configuration for flask-oauthlib::
'request_token_url':None,
'access_token_url':'https://accounts.google.com/o/oauth2/token',
'authorize_url':'https://accounts.google.com/o/oauth2/auth'}
}
},
{
'name': 'okta',
'icon': 'fa-circle-o',
'token_key': 'access_token',
'remote_app': {
'consumer_key': 'OKTA_KEY',
'consumer_secret': 'OKTA_SECRET',
'base_url': 'https://OKTA_DOMAIN.okta.com/oauth2/v1/',
'request_token_params': {
'scope': 'openid profile email groups'
},
'access_token_url': 'https://OKTA_DOMAIN.okta.com/oauth2/v1/token',
'authorize_url': 'https://OKTA_DOMAIN.okta.com/oauth2/v1/authorize',
},
},
]

This needs a small explanation, you basically have five special keys:

:name: The name of the provider, you can choose whatever you want. But the framework as some
builtin logic to retrieve information about a user that you can make use of if you choose:
'twitter', 'google', 'github','linkedin'.
'twitter', 'google', 'github', 'linkedin', 'okta'.

:icon: The font-awesome icon for this provider.
:token_key: The token key name that this provider uses, google and github uses *'access_token'*,
Expand Down Expand Up @@ -523,6 +544,78 @@ this provider with, **response** is the response.

Take a look at the `example <https://github.com/dpgaspar/Flask-AppBuilder/tree/master/examples/oauth>`_

Role Binding
--------------------

:note: currently we only support binding external groups into FAB roles from: AUTH_LDAP, AUTH_OAUTH (Okta)

If you have an external source of truth for groups, you might want to have FAB sync user's roles from that system
as they login.

Here is an example config for LDAP, (Note this is for Okta LDAP, but can be extended to any LDAP provider)::

# Force users to re-auth after 15min of inactivity
# NOTE: this is important to keep roles in sync
PERMANENT_SESSION_LIFETIME = 900

AUTH_USER_REGISTRATION = True
AUTH_USER_REGISTRATION_ROLE = "Viewer"

AUTH_ROLES_SYNC_AT_LOGIN = True
AUTH_ROLES_MAPPING = {
"cn=User,ou=groups,dc=OKTA_DOMAIN,dc=com": "User",
"cn=Admin,ou=groups,dc=OKTA_DOMAIN,dc=com": "Admin",
}

AUTH_TYPE = AUTH_LDAP
AUTH_LDAP_SERVER = "ldaps://OKTA_DOMAIN.ldap.okta.com:636"
AUTH_LDAP_USE_TLS = False

AUTH_LDAP_BIND_USER = "uid=bind-admin,dc=OKTA_DOMAIN,dc=okta,dc=com"
AUTH_LDAP_BIND_PASSWORD = "xxxxxxxxxxxx"

AUTH_LDAP_SEARCH = "ou=users,dc=OKTA_DOMAIN,dc=okta,dc=com"
AUTH_LDAP_SEARCH_FILTER = "(objectclass=inetOrgPerson)"
AUTH_LDAP_APPEND_DOMAIN = "OKTA_DOMAIN.com"

AUTH_LDAP_UID_FIELD = "uid"
AUTH_LDAP_GROUP_FIELD = "memberOf"
AUTH_LDAP_FIRSTNAME_FIELD = "givenName"
AUTH_LDAP_LASTNAME_FIELD = "sn"
AUTH_LDAP_EMAIL_FIELD = "email"

Here is an example config for OAUTH, (Note this is for Okta OAUTH)::

# Force users to re-auth after 15min of inactivity
# NOTE: this is important to keep roles in sync
PERMANENT_SESSION_LIFETIME = 900

AUTH_USER_REGISTRATION = True
AUTH_USER_REGISTRATION_ROLE = "Viewer"

AUTH_ROLES_SYNC_AT_LOGIN = True
AUTH_ROLES_MAPPING = {
"USER_GROUP_NAME": "User",
"ADMIN_GROUP_NAME": "Admin",
}

OAUTH_PROVIDERS = [
{
"name": "okta",
"icon": "fa-circle-o",
"token_key": "access_token",
"remote_app": {
"consumer_key": "OKTA_KEY",
"consumer_secret": "OKTA_SECRET",
"base_url": "https://OKTA_DOMAIN.okta.com/oauth2/v1/",
"request_token_params": {
"scope": "openid profile email groups"
},
"access_token_url": "https://OKTA_DOMAIN.okta.com/oauth2/v1/token",
"authorize_url": "https://OKTA_DOMAIN.okta.com/oauth2/v1/authorize",
}
]

Your Custom Security
--------------------

Expand Down
29 changes: 29 additions & 0 deletions examples/oauth/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,21 @@
"authorize_url": "https://login.microsoftonline.com/{AZURE_TENANT_ID}/oauth2/authorize",
},
},
{
"name": "okta",
"icon": "fa-circle-o",
"token_key": "access_token",
"remote_app": {
"consumer_key": os.environ.get("OKTA_KEY"),
"consumer_secret": os.environ.get("OKTA_SECRET"),
"base_url": "https://{}.okta.com/oauth2/v1/".format(os.environ.get("OKTA_DOMAIN")),
"request_token_params": {
"scope": "openid profile email groups"
},
"access_token_url": "https://{}.okta.com/oauth2/v1/token".format(os.environ.get("OKTA_DOMAIN")),
"authorize_url": "https://{}.okta.com/oauth2/v1/authorize".format(os.environ.get("OKTA_DOMAIN")),
},
},
]

# Uncomment to setup Full admin role name
Expand All @@ -97,6 +112,20 @@
# The default user self registration role
AUTH_USER_REGISTRATION_ROLE = "Admin"

# Replace users database roles each login with those received from OAUTH/LDAP
AUTH_ROLES_SYNC_AT_LOGIN = True

# A mapping from LDAP/OAUTH group names to FAB roles
AUTH_ROLES_MAPPING = {
# For OAUTH
"USER_GROUP_NAME": "User",
"ADMIN_GROUP_NAME": "Admin",

# For LDAP
# "cn=User,ou=groups,dc=example,dc=com": "User",
# "cn=Admin,ou=groups,dc=example,dc=com": "Admin",
}

# When using LDAP Auth, setup the ldap server
# AUTH_LDAP_SERVER = "ldap://ldapserver.new"
# AUTH_LDAP_USE_TLS = False
Expand Down
Loading

0 comments on commit f73929d

Please sign in to comment.