Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
visa-jupyter
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
PaNOSC
Data Analysis Services
visa-jupyter
Commits
9db3f42a
Commit
9db3f42a
authored
Jun 14, 2019
by
Eric Pellegrini
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added keycloak class directly in JupyterHubConfig
parent
0bdb18fb
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
113 additions
and
8 deletions
+113
-8
ansible/roles/setup-visa-jupyter-environment/templates/jupyterhub_config.py.j2
...isa-jupyter-environment/templates/jupyterhub_config.py.j2
+107
-8
ansible/roles/setup-visa-jupyter-service/templates/visa-jupyter-envvar.j2
...tup-visa-jupyter-service/templates/visa-jupyter-envvar.j2
+4
-0
ansible/roles/setup-visa-jupyter-service/vars/oauth.yml
ansible/roles/setup-visa-jupyter-service/vars/oauth.yml
+2
-0
No files found.
ansible/roles/setup-visa-jupyter-environment/templates/jupyterhub_config.py.j2
View file @
9db3f42a
# Configuration file for jupyterhub.
import os
import json
import os
import sys
import tempfile
import urllib
from tornado import gen, web
from tornado.auth import OAuth2Mixin
from tornado.httpclient import HTTPRequest, AsyncHTTPClient
from tornado.httputil import url_concat
from jupyterhub.auth import LocalAuthenticator
from jupyterhub.handlers import LogoutHandler
from jupyterhub.utils import url_path_join
from oauthenticator.oauth2 import OAuthLoginHandler, OAuthenticator
class KeycloakMixin(OAuth2Mixin):
_OAUTH_AUTHORIZE_URL = os.getenv("OAUTH2_AUTHORIZE_URL", "https://login.ill.fr/auth/realms/ILL/protocol/openid-connect/auth")
_OAUTH_ACCESS_TOKEN_URL = os.getenv("OAUTH2_TOKEN_URL" , "https://login.ill.fr/auth/realms/ILL/protocol/openid-connect/token")
_OAUTH_LOGOUT_URL = os.getenv("OAUTH2_LOGOUT_URL" , "https://login.ill.fr/auth/realms/ILL/protocol/openid-connect/logout")
_OAUTH_USERINFO_URL = os.getenv("OAUTH2_USERINFO_URL" , "https://login.ill.fr/auth/realms/ILL/protocol/openid-connect/userinfo")
class KeycloakLoginHandler(OAuthLoginHandler, KeycloakMixin):
pass
class KeycloakLogoutHandler(LogoutHandler, KeycloakMixin):
def get(self):
# Get the current user and clear its login cookie
user = self.get_current_user()
if user:
self.log.info("User logged out: %s", user.name)
self.clear_login_cookie()
self.statsd.incr('logout')
# The logout will access login.ill.fr keycloak logout which will further redirect to jupyterhub login page
params = dict(redirect_uri="%s://%s%slogin" % (self.request.protocol, self.request.host,self.hub.server.base_url))
logout_url = KeycloakMixin._OAUTH_LOGOUT_URL
logout_url = url_concat(logout_url, params)
self.redirect(logout_url, permanent=False)
class KeycloakOAuthenticator(OAuthenticator, KeycloakMixin):
login_service = "Keycloak"
login_handler = KeycloakLoginHandler
def logout_url(self, base_url):
return url_path_join(base_url, 'oauth_logout')
def get_handlers(self, app):
handlers = OAuthenticator.get_handlers(self, app)
# Override the logout handler with the keycloak logout handler
handlers.extend([(r'/logout', KeycloakLogoutHandler)])
handlers.extend([(r'/oauth_logout', KeycloakLogoutHandler)])
return handlers
@gen.coroutine
def authenticate(self, handler, data=None):
code = handler.get_argument("code", False)
if not code:
raise web.HTTPError(400, "oauth callback made without a token")
http_client = AsyncHTTPClient()
params = dict(
grant_type='authorization_code',
code=code,
redirect_uri=self.get_callback_url(handler),
)
tokenUrl = KeycloakMixin._OAUTH_ACCESS_TOKEN_URL
tokenReq = HTTPRequest(tokenUrl,
method="POST",
headers={"Accept": "application/json",
"Content-Type": "application/x-www-form-urlencoded;charset=utf-8"},
auth_username=self.client_id,
auth_password=self.client_secret,
body=urllib.parse.urlencode(params).encode(
'utf-8'),
)
tokenResp = yield http_client.fetch(tokenReq)
tokenResp_json = json.loads(tokenResp.body.decode('utf8', 'replace'))
access_token = tokenResp_json['access_token']
if not access_token:
raise web.HTTPError(400, "failed to get access token")
self.log.info('oauth token: %r', access_token)
userInfoUrl = KeycloakMixin._OAUTH_USERINFO_URL
userInfoReq = HTTPRequest(userInfoUrl,
method="GET",
headers={"Accept": "application/json",
"Authorization": "Bearer %s" % access_token},
)
userInfoResp = yield http_client.fetch(userInfoReq)
userInfoResp_json = json.loads(
userInfoResp.body.decode('utf8', 'replace'))
return userInfoResp_json['preferred_username']
class LocalKeycloakOAuthenticator(LocalAuthenticator, KeycloakOAuthenticator):
"""A version that mixes in local system user creation"""
pass
bin_dir = os.path.split(sys.executable)[0]
spawner = os.path.join(bin_dir, 'sudospawner')
...
...
@@ -23,7 +129,6 @@ c.JupyterHub.db_url = database
c.JupyterHub.cookie_secret_file = cookie
c.SudoSpawner.sudospawner_path = spawner
import os
visa_jupyter_client_secret = os.environ.get("VISA_JUPYTER_CLIENT_SECRET",None)
if not visa_jupyter_client_secret:
raise RuntimeError("The VISA_JUPYTER_CLIENT_SECRET env var is not defined")
...
...
@@ -31,15 +136,9 @@ if not visa_jupyter_client_secret:
import socket
hostname = socket.gethostname()
# Use the keycloak oauthenticator
from oauthenticator.generic import GenericOAuthenticator
c.JupyterHub.authenticator_class = GenericOAuthenticator
c.JupyterHub.authenticator_class = KeycloakOAuthenticator
c.OAuthenticator.client_id = hostname
c.OAuthenticator.client_secret = visa_jupyter_client_secret
c.OAuthenticator.logout_url = lambda base_url : "https://login.ill.fr/auth/realms/ILL/protocol/openid-connect/logout"
c.OAuthenticator.userdata_method = "GET"
c.OAuthenticator.userdata_params = {"state": "state"}
c.OAuthenticator.username_key = "preferred_username"
# Here are the jupyter infrastructure admins
c.Authenticator.admin_users = {"pellegrini","pinet","hall","caunt","perrin"}
...
...
ansible/roles/setup-visa-jupyter-service/templates/visa-jupyter-envvar.j2
View file @
9db3f42a
...
...
@@ -2,4 +2,8 @@ OAUTH2_AUTHORIZE_URL={{oauth2_authorize_url}}
OAUTH2_TOKEN_URL={{oauth2_token_url}}
OAUTH2_USERINFO_URL={{oauth2_userinfo_url}}
OAUTH2_LOGOUT_URL={{oauth2_logout_url}}
VISA_JUPYTER_CLIENT_SECRET={{visa_jupyter_client_secret}}
ansible/roles/setup-visa-jupyter-service/vars/oauth.yml
View file @
9db3f42a
---
oauth2_authorize_url
:
"
{{
lookup('env','OAUTH2_AUTHORIZE_URL')
}}"
oauth2_token_url
:
"
{{
lookup('env','OAUTH2_TOKEN_URL')
}}"
oauth2_userinfo_url
:
"
{{
lookup('env','OAUTH2_USERINFO_URL')
}}"
oauth2_logout_url
:
"
{{
lookup('env','OAUTH2_LOGOUT_URL')
}}"
visa_jupyter_client_secret
:
"
{{
lookup('env','VISA_JUPYTER_CLIENT_SECRET')
}}"
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment