在自定义 Jupyterhub 验证器中设置 spawner 环境变量
Set spawner environment variables in custom Jupyterhub authenticator
我正在尝试使用 Jupyterhub 的远程身份验证插件,但也使用它为生成的用户将数据保存到 auth_state
属性。
在很大程度上基于 Remote User Authenticator,我使用它来创建用户并通过读取查询参数创建会话。
import os
import pprint
from jupyterhub.handlers import BaseHandler
from jupyterhub.auth import Authenticator
from jupyterhub.utils import url_path_join
from tornado import gen, web
from traitlets import Unicode
class InkspotUserLoginHandler(BaseHandler):
def get(self):
inkspot_user = self.get_argument('user', None, True)
inkspot_study = self.get_argument('studyFolder', None, True)
if inkspot_user == "":
raise web.HTTPError(401)
if inkspot_study == "":
raise web.HTTPError(401)
user = self.user_from_username(inkspot_user)
self.set_login_cookie(user)
next_url = self.get_next_url(user)
self.redirect(next_url)
class InkspotUserAuthenticator(Authenticator):
"""
Accept the authenticated user name from the user query parameter.
"""
def get_handlers(self, app):
return [
(r'/login', InkspotUserLoginHandler),
]
@gen.coroutine
def authenticate(self, handler, data):
raise NotImplementedError()
但是,我需要根据发送到验证器的其他查询参数在生成器中设置环境变量。我在文档中看到 code example 使用 auth_state
作为存储数据的方式,这些数据可以被 pre_spawn_start
挂钩访问,但看不到它如何与代码一起工作我有。文档中的代码如下所示:
class MyAuthenticator(Authenticator):
@gen.coroutine
def authenticate(self, handler, data=None):
username = yield identify_user(handler, data)
upstream_token = yield token_for_user(username)
return {
'name': username,
'auth_state': {
'upstream_token': upstream_token,
},
}
@gen.coroutine
def pre_spawn_start(self, user, spawner):
"""Pass upstream_token to spawner via environment variable"""
auth_state = yield user.get_auth_state()
if not auth_state:
# auth_state not enabled
return
spawner.environment['UPSTREAM_TOKEN'] = auth_state['upstream_token']
我的自定义处理程序没有 return 任何东西,它会重定向 - 这可能就是为什么身份验证方法 return 是 NotImplementedError
.
的原因
我缺少什么可以让我在现有代码中使用 pre_spawn_start
挂钩?
方法是实现 authenticate 方法并将查询参数作为数据字典传递给它。
import os
import pprint
from jupyterhub.handlers import BaseHandler
from jupyterhub.auth import Authenticator
from jupyterhub.utils import url_path_join
from tornado import gen, web
from traitlets import Unicode
class InkspotUserLoginHandler(BaseHandler):
@gen.coroutine
def get(self):
inkspot_user = self.get_argument('user', None, True)
inkspot_study = self.get_argument('studyFolder', None, True)
if inkspot_user == "":
raise web.HTTPError(401)
if inkspot_study == "":
raise web.HTTPError(401)
userDict = {
'name': inkspot_user,
'studyFolder': inkspot_study
}
user = yield self.login_user(userDict)
next_url = self.get_next_url(user)
self.redirect(next_url)
class InkspotUserAuthenticator(Authenticator):
"""
Accept the authenticated user name from the user query parameter.
"""
def get_handlers(self, app):
return [
(r'/login', InkspotUserLoginHandler),
]
@gen.coroutine
def authenticate(self, handler, data):
return {
'name': data['name'],
'auth_state': {
'studyFolder': data['studyFolder']
}
}
@gen.coroutine
def pre_spawn_start(self, user, spawner):
"""Pass inkspot data to spawner via environment variable"""
auth_state = yield user.get_auth_state()
if not auth_state:
# auth_state not enabled
self.log.debug('auth_state not enabled')
return
spawner.environment['STUDY_FOLDER'] = auth_state['studyFolder']
我正在尝试使用 Jupyterhub 的远程身份验证插件,但也使用它为生成的用户将数据保存到 auth_state
属性。
在很大程度上基于 Remote User Authenticator,我使用它来创建用户并通过读取查询参数创建会话。
import os
import pprint
from jupyterhub.handlers import BaseHandler
from jupyterhub.auth import Authenticator
from jupyterhub.utils import url_path_join
from tornado import gen, web
from traitlets import Unicode
class InkspotUserLoginHandler(BaseHandler):
def get(self):
inkspot_user = self.get_argument('user', None, True)
inkspot_study = self.get_argument('studyFolder', None, True)
if inkspot_user == "":
raise web.HTTPError(401)
if inkspot_study == "":
raise web.HTTPError(401)
user = self.user_from_username(inkspot_user)
self.set_login_cookie(user)
next_url = self.get_next_url(user)
self.redirect(next_url)
class InkspotUserAuthenticator(Authenticator):
"""
Accept the authenticated user name from the user query parameter.
"""
def get_handlers(self, app):
return [
(r'/login', InkspotUserLoginHandler),
]
@gen.coroutine
def authenticate(self, handler, data):
raise NotImplementedError()
但是,我需要根据发送到验证器的其他查询参数在生成器中设置环境变量。我在文档中看到 code example 使用 auth_state
作为存储数据的方式,这些数据可以被 pre_spawn_start
挂钩访问,但看不到它如何与代码一起工作我有。文档中的代码如下所示:
class MyAuthenticator(Authenticator):
@gen.coroutine
def authenticate(self, handler, data=None):
username = yield identify_user(handler, data)
upstream_token = yield token_for_user(username)
return {
'name': username,
'auth_state': {
'upstream_token': upstream_token,
},
}
@gen.coroutine
def pre_spawn_start(self, user, spawner):
"""Pass upstream_token to spawner via environment variable"""
auth_state = yield user.get_auth_state()
if not auth_state:
# auth_state not enabled
return
spawner.environment['UPSTREAM_TOKEN'] = auth_state['upstream_token']
我的自定义处理程序没有 return 任何东西,它会重定向 - 这可能就是为什么身份验证方法 return 是 NotImplementedError
.
我缺少什么可以让我在现有代码中使用 pre_spawn_start
挂钩?
方法是实现 authenticate 方法并将查询参数作为数据字典传递给它。
import os
import pprint
from jupyterhub.handlers import BaseHandler
from jupyterhub.auth import Authenticator
from jupyterhub.utils import url_path_join
from tornado import gen, web
from traitlets import Unicode
class InkspotUserLoginHandler(BaseHandler):
@gen.coroutine
def get(self):
inkspot_user = self.get_argument('user', None, True)
inkspot_study = self.get_argument('studyFolder', None, True)
if inkspot_user == "":
raise web.HTTPError(401)
if inkspot_study == "":
raise web.HTTPError(401)
userDict = {
'name': inkspot_user,
'studyFolder': inkspot_study
}
user = yield self.login_user(userDict)
next_url = self.get_next_url(user)
self.redirect(next_url)
class InkspotUserAuthenticator(Authenticator):
"""
Accept the authenticated user name from the user query parameter.
"""
def get_handlers(self, app):
return [
(r'/login', InkspotUserLoginHandler),
]
@gen.coroutine
def authenticate(self, handler, data):
return {
'name': data['name'],
'auth_state': {
'studyFolder': data['studyFolder']
}
}
@gen.coroutine
def pre_spawn_start(self, user, spawner):
"""Pass inkspot data to spawner via environment variable"""
auth_state = yield user.get_auth_state()
if not auth_state:
# auth_state not enabled
self.log.debug('auth_state not enabled')
return
spawner.environment['STUDY_FOLDER'] = auth_state['studyFolder']