question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Working configuration for generic authenticator with Keycloak

See original GitHub issue

I have tried to configure Jupyterhub to use the generic OAuth2 authentication mechanism with Keycloak as OAuth2 sever. However, it never redirects to it for authentication. Could you please support me and provide a sample configuration that is supposed to work? Or is there anything that I’m obviously doing wrong?

Thank you very much! Dennis

OAuthenticator configuration in jupyterhub_config.py:

from oauthenticator.generic import GenericOAuthenticator
c.JupyterHub.authenticator_class = GenericOAuthenticator

c.GenericOAuthenticator.oauth_callback_url = 'https://example.com:8443/auth/realms/testrealm/protocol/openid-connect/auth'
c.GenericOAuthenticator.client_id = 'oauth-secret'
c.GenericOAuthenticator.client_secret = 'asfdsdf-dfdf-fhhfh-aed7-asdafsdfsaf'
c.GenericOAuthenticator.token_url = 'https://example.com:8443/auth/realms/testrealm/protocol/openid-connect/token'
c.GenericOAuthenticator.userdata_url = 'https://141.72.18.234:8443/auth/realms/testrealm/protocol/openid-connect/userinfo'

Keycloak Endpoints:

{
	"issuer": "https://example.com:8443/auth/realms/testrealm",
	"authorization_endpoint": "https://example.com:8443/auth/realms/testrealm/protocol/openid-connect/auth",
	"token_endpoint": "https://example.com:8443/auth/realms/testrealm/protocol/openid-connect/token",
	"token_introspection_endpoint": "https://example.com:8443/auth/realms/testrealm/protocol/openid-connect/token/introspect",
	"userinfo_endpoint": "https://example.com:8443/auth/realms/testrealm/protocol/openid-connect/userinfo",
	"end_session_endpoint": "https://example.com:8443/auth/realms/testrealm/protocol/openid-connect/logout",
	"jwks_uri": "https://example.com:8443/auth/realms/testrealm/protocol/openid-connect/certs",
	"check_session_iframe": "https://example.com:8443/auth/realms/testrealm/protocol/openid-connect/login-status-iframe.html",
	"grant_types_supported": ["authorization_code", "implicit", "refresh_token", "password", "client_credentials"],
	"response_types_supported": ["code", "none", "id_token", "token", "id_token token", "code id_token", "code token", "code id_token token"],
	"subject_types_supported": ["public", "pairwise"],
	"id_token_signing_alg_values_supported": ["RS256"],
	"userinfo_signing_alg_values_supported": ["RS256"],
	"request_object_signing_alg_values_supported": ["none", "RS256"],
	"response_modes_supported": ["query", "fragment", "form_post"],
	"registration_endpoint": "https://example.com:8443/auth/realms/testrealm/clients-registrations/openid-connect",
	"token_endpoint_auth_methods_supported": ["private_key_jwt", "client_secret_basic", "client_secret_post"],
	"token_endpoint_auth_signing_alg_values_supported": ["RS256"],
	"claims_supported": ["sub", "iss", "auth_time", "name", "given_name", "family_name", "preferred_username", "email"],
	"claim_types_supported": ["normal"],
	"claims_parameter_supported": false,
	"scopes_supported": ["openid", "offline_access"],
	"request_parameter_supported": true,
	"request_uri_parameter_supported": true
}

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:48 (14 by maintainers)

github_iconTop GitHub Comments

6reactions
t20100commented, Feb 3, 2021

If that can help, I got logout with keycloak working with oauthenticator 0.11.0 with the following code:

An authenticator with a LogoutHandler since the default one does not handles logout against authentication service:

from traitlets import Unicode
from oauthenticator.generic import GenericOAuthenticator
from jupyterhub.utils import url_path_join
from jupyterhub.handlers.login import LogoutHandler
from tornado.httputil import url_concat

class KeycloakLogoutHandler(LogoutHandler):
    """Logout handler for keycloak"""

    async def render_logout_page(self):
        params = {
            'redirect_uri': '%s://%s%s' % (
                self.request.protocol,
                self.request.host,
                self.hub.server.base_url),
            }
        self.redirect(
            url_concat(self.authenticator.keycloak_logout_url, params),
            permanent=False
        )

class KeycloakAuthenticator(GenericOAuthenticator):
    """Authenticator handling keycloak logout"""

    keycloak_logout_url = Unicode(
        config=True,
        help="The keycloak logout URL"
    )

    def get_handlers(self, app):
        return super().get_handlers(app) + [(r'/logout', KeycloakLogoutHandler)]

And then use the authenticator and logout URL configuration:

c.JupyterHub.authenticator_class = KeycloakAuthenticator
c.KeycloakAuthenticator.keycloak_logout_url = "https://example.com/auth/realms/REALM/protocol/openid-connect/logout"

I don’t know how much that can be generalized, but when using keycloak that would be great to have the logout handled by default.

3reactions
patback66commented, Sep 27, 2017

Censored some bits but here’s the config for authentication:

from oauthenticator.generic import LocalGenericOAuthenticator
c.JupyterHub.authenticator_class = LocalGenericOAuthenticator
c.OAuthenticator.client_id = '{client_id}'
c.OAuthenticator.client_secret = '{client_secret}'
c.LocalGenericOAuthenticator.token_url = 'https://{domain}:{port}/auth/realms/{realm}/protocol/openid-connect/token'# oauth2 provider's token url
c.LocalGenericOAuthenticator.userdata_url = 'https://{domain}:{port}/auth/realms/{realm}/protocol/openid-connect/userinfo'
c.LocalGenericOAuthenticator.userdata_method = 'GET'
c.LocalGenericOAuthenticator.userdata_params = {"state": "state"}
c.LocalGenericOAuthenticator.username_key = "preferred_username"
c.LocalAuthenticator.create_system_users = True

and env vars

OAUTH2_AUTHORIZE_URL=https://{domain}:{port}/auth/realms/{realm}/protocol/openid-connect/auth
OAUTH2_TOKEN_URL=https:/{domain}:{port}/auth/realms/{realm}/protocol/openid-connect/token

Should I be setting something like c.Authenticator.auto_login = True to get the intended behavior?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Server Administration Guide - Keycloak
Keycloak can be configured to delegate authentication to one or more IDPs. Social login via Facebook or Google+ is an example of identity ......
Read more >
Securing Applications and Services Guide - Keycloak
Configure a client using one of these options: A Keycloak adapter. A generic OpenID connect or SAML library. Register a client using one...
Read more >
Server Developer Guide - Keycloak
The isConfigurable() method is a flag which specifies to the Admin Console on whether the Authenticator can be configured within a flow. The ......
Read more >
Server Administration Guide - Keycloak
Keycloak can be configured to delegate authentication to one or more IDPs. Social login via Facebook or Google+ is an example of identity ......
Read more >
Authorization Services Guide - Keycloak
When you enable authorization services for a client application, Keycloak automatically creates several default settings for your client ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found