【问题标题】:How to access current user/auth_state from notebook如何从笔记本访问当前用户/auth_state
【发布时间】:2018-12-19 15:23:14
【问题描述】:

我正在使用带有自定义身份验证器的 JupyterHub。 它使用访问令牌设置 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']

但是,每个用户只发生一次。如果我注销并再次登录,则不会再次调用 pre_spawn_start 并且旧令牌仍存在于环境变量中。

是否可以直接从笔记本访问user.get_auth_state(),这样我就可以确保使用当前令牌,而不是之前设置并存储在环境中?

否则,是否可以在注销时强制 spawner 停止,以便后续登录将触发 pre_spawn_start

【问题讨论】:

  • 也许,(只是也许)你可以在配置文件中添加 c.Authenticator.refresh_pre_spawn = True (这就是我在相同的设置和工作中所拥有的)
  • 我也有同样的问题。你是如何解决这个问题的?你用了 refresh_user 吗?

标签: jupyter-notebook jupyterhub


【解决方案1】:

你可以在token过期时强制停止服务器并要求登录,可以通过以下步骤实现,

  1. 编写refresh_user方法获取新token(附示例代码)
  2. 为 refresh_user 设置时间。
    • c.MyAuthenticator.auth_refresh_age = 30 #这可能是令牌的有效时间,以秒为单位
import inspect, concurrent,asyncio

async def refresh_user(self, user,handler=None):
    """
    1. Check if token is valid and then call _shutdown_servers and then redirect to login page
    2. If time of refresh_user is set as token expiry, directly call _shutdown_servers and then redirect to login page
    This is shutdown single user servers and once redirected to login, auth flow gets run and new tokens are passed to spawner
    """
    auth_state = await user.get_auth_state()
    if self._is_invalid_sessionid(auth_state):
        await self._shutdown_servers(user, handler=None)
        handler.clear_login_cookie()
        handler.redirect('/login')
    return True

async def maybe_future(obj):
    """Return an asyncio Future
    Use instead of gen.maybe_future
    For our compatibility, this must accept:
    - asyncio coroutine (gen.maybe_future doesn't work in tornado < 5)
    - tornado coroutine (asyncio.ensure_future doesn't work)
    - scalar (asyncio.ensure_future doesn't work)
    - concurrent.futures.Future (asyncio.ensure_future doesn't work)
    - tornado Future (works both ways)
    - asyncio Future (works both ways)
    """
    if inspect.isawaitable(obj):
        # already awaitable, use ensure_future
        return asyncio.ensure_future(obj)
    elif isinstance(obj, concurrent.futures.Future):
        return asyncio.wrap_future(obj)
    else:
        # could also check for tornado.concurrent.Future
        # but with tornado >= 5.1 tornado.Future is asyncio.Future
        f = asyncio.Future()
        f.set_result(obj)
        return f

async def _shutdown_servers(self, user,handler):
    """Shutdown servers for logout
    Get all active servers for the provided user, stop them.
    """
    active_servers = [
        name
        for (name, spawner) in user.spawners.items()
        if spawner.active and not spawner.pending
    ]
    if active_servers:
        self.log.info("Shutting down %s's servers", user.name)
        futures = []
        for server_name in active_servers:
            futures.append(self.maybe_future(handler.stop_single_user(user, server_name)))
        await asyncio.gather(*futures)

https://jupyterhub.readthedocs.io/en/stable/api/auth.html#jupyterhub.auth.Authenticator.auth_refresh_age https://jupyterhub.readthedocs.io/en/stable/api/auth.html#jupyterhub.auth.Authenticator.refresh_user

【讨论】:

    【解决方案2】:

    似乎这个 c.Authenticator.refresh_pre_spawn = True,正如 Eos Antigen 所建议的那样解决了这个问题:每次您再次登录时,预生成定义的函数都会再次执行。

    【讨论】:

    • refresh_pre_spawn 只是在 spawn 之前强制刷新 auth(refresh_user() 方法在启动服务器之前被调用),它不会再次调用 pre_spawn() 方法。
    猜你喜欢
    • 2019-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多