Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AzureAD] Add an implementation for Authenticator.authenticator_managed_groups=true #448

Closed

Conversation

thomafred
Copy link
Contributor

See this related PR in jupyterhub/jupyterhub-repo.

Added support for external user group management to Azure AD authenticator.

Usage example:

"""sample jupyterhub config file for testing

configures jupyterhub with dummyauthenticator and simplespawner
to enable testing without administrative privileges.
"""

c = get_config()  # noqa
c.Application.log_level = 'DEBUG'

from oauthenticator.azuread import AzureAdOAuthenticator
import os

c.JupyterHub.authenticator_class = AzureAdOAuthenticator

c.AzureAdOAuthenticator.client_id = os.getenv("AAD_CLIENT_ID")
c.AzureAdOAuthenticator.client_secret = os.getenv("AAD_CLIENT_SECRET")
c.AzureAdOAuthenticator.oauth_callback_url = os.getenv("AAD_CALLBACK_URL")
c.AzureAdOAuthenticator.tenant_id = os.getenv("AAD_TENANT_ID")
c.AzureAdOAuthenticator.username_claim = "email"
c.AzureAdOAuthenticator.authorize_url = os.getenv("AAD_AUTHORIZE_URL")
c.AzureAdOAuthenticator.token_url = os.getenv("AAD_TOKEN_URL")
c.Authenticator.authenticator_managed_groups = True
c.Authenticator.refresh_pre_spawn = True

from jupyterhub.spawner import SimpleLocalProcessSpawner

c.JupyterHub.spawner_class = SimpleLocalProcessSpawner

Signed-off-by: Thomas Li Fredriksen <thomas.fredriksen@oceandata.earth>
@welcome
Copy link

welcome bot commented Jul 23, 2021

Thanks for submitting your first pull request! You are awesome! 🤗

If you haven't done so already, check out Jupyter's Code of Conduct. Also, please make sure you followed the pull request template, as this will help us review your contribution more quickly.
welcome
You can meet the other Jovyans by joining our Discourse forum. There is also a intro thread there where you can stop by and say Hi! 👋

Welcome to the Jupyter community! 🎉

Comment on lines +106 to +108
def load_user_groups(self, auth_state):
auth_user_state = auth_state["auth_state"]["user"]
return auth_user_state[self.user_groups_claim]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we assume auth_user_state always include a claim named groups? Does it imply that you have requested the scope groups as well or not?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the load_user_groups function an Authenticator base class function that is overridden?

Copy link
Member

@consideRatio consideRatio Aug 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm, what is calling this function? I find no reference to it in this repo or the Authenticator base class definition.

Also I found no reference to the authenticator_managed_groups configuration that is configuredin the configuration example you provide within the Authenticator base class.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, this PR relies on jupyterhub/jupyterhub#3548.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@consideRatio - Unsure whether auth_user_state will return with a groups-claim.

The functionality in this PR requires auth_users_state to return some claim with a list of groups if c.Authenticator.authenticator_managed_groups = True. The claim name itself is configurable.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The groups-claim is non standard for OIDC, but AAD makes it available as an optional claim
https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-optional-claims.

In our case we extend our AAD's policy to make API calls to fetch and return group membership, as shown in this example: https://github.com/azure-ad-b2c/samples/tree/master/policies/rest-api-idp

…configs

Signed-off-by: Thomas Li Fredriksen <thomas.fredriksen@oceandata.earth>
Signed-off-by: Thomas Li Fredriksen <thomas.fredriksen@oceandata.earth>
Comment on lines +45 to +47
@default('user_groups_claim')
def _user_groups_claim_default(self):
return 'groups'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you have a default that is fixed like this, you can have it as the first argument passed to the Unicode constructor above instead.

@consideRatio consideRatio changed the title Azure AD - Added support for external user group management [AzureAD] Add an implementation for Authenticator.authenticator_managed_groups=true May 21, 2022
@thomafred thomafred closed this Feb 7, 2023
@thomafred
Copy link
Contributor Author

Abandoned in favor of this PR: #573

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants