mirror of
https://github.com/jupyter/notebook.git
synced 2025-02-05 12:19:58 +08:00
use one-time token for opening browser
first connection consumes the token, so command-line snoops can’t re-use it.
This commit is contained in:
parent
3ba68d8cb7
commit
cd3c6c1b8a
@ -98,7 +98,8 @@ class LoginHandler(IPythonHandler):
|
||||
"""
|
||||
# Can't call this get_current_user because it will collide when
|
||||
# called on LoginHandler itself.
|
||||
|
||||
if getattr(handler, '_user_id', None):
|
||||
return handler._user_id
|
||||
user_id = handler.get_secure_cookie(handler.cookie_name)
|
||||
if not user_id:
|
||||
# prevent extra Invalid cookie sig warnings:
|
||||
@ -111,11 +112,20 @@ class LoginHandler(IPythonHandler):
|
||||
if login_token:
|
||||
# check login token
|
||||
user_token = handler.get_argument('token', '')
|
||||
one_time_token = handler.settings.get('one_time_token', None)
|
||||
if user_token == login_token:
|
||||
# token-authenticated, set the login cookie
|
||||
user_id = uuid.uuid4().hex
|
||||
handler.log.info("Accepting token-authenticated connection from %s", handler.request.remote_ip)
|
||||
user_id = uuid.uuid4().hex
|
||||
cls.set_login_cookie(handler, user_id)
|
||||
if one_time_token and user_token == one_time_token:
|
||||
# one-time token-authenticated, only allow this token once
|
||||
handler.settings.pop('one_time_token', None)
|
||||
handler.log.info("Accepting one-time-token-authenticated connection from %s", handler.request.remote_ip)
|
||||
user_id = uuid.uuid4().hex
|
||||
cls.set_login_cookie(handler, user_id)
|
||||
# cache value for future retrievals on the same request
|
||||
handler._user_id = user_id
|
||||
return user_id
|
||||
|
||||
|
||||
|
@ -585,6 +585,13 @@ class NotebookApp(JupyterApp):
|
||||
"""
|
||||
).tag(config=True)
|
||||
|
||||
one_time_token = Unicode(
|
||||
help="""One-time token used for opening a browser.
|
||||
|
||||
Once used, this token cannot be used again.
|
||||
"""
|
||||
)
|
||||
|
||||
@default('login_token')
|
||||
def _login_token_default(self):
|
||||
if self.password:
|
||||
@ -1015,6 +1022,10 @@ class NotebookApp(JupyterApp):
|
||||
self.tornado_settings['allow_credentials'] = self.allow_credentials
|
||||
self.tornado_settings['cookie_options'] = self.cookie_options
|
||||
self.tornado_settings['login_token'] = self.login_token
|
||||
if (self.open_browser or self.file_to_run) and not self.password:
|
||||
self.one_time_token = binascii.hexlify(os.urandom(24)).decode('ascii')
|
||||
self.tornado_settings['one_time_token'] = self.one_time_token
|
||||
|
||||
# ensure default_url starts with base_url
|
||||
if not self.default_url.startswith(self.base_url):
|
||||
self.default_url = url_path_join(self.base_url, self.default_url)
|
||||
@ -1302,8 +1313,8 @@ class NotebookApp(JupyterApp):
|
||||
else:
|
||||
# default_url contains base_url, but so does connection_url
|
||||
uri = self.default_url[len(self.base_url):]
|
||||
if self.login_token:
|
||||
uri = url_concat(uri, {'token': self.login_token})
|
||||
if self.one_time_token:
|
||||
uri = url_concat(uri, {'token': self.one_time_token})
|
||||
if browser:
|
||||
b = lambda : browser.open(url_path_join(self.connection_url, uri),
|
||||
new=2)
|
||||
@ -1322,7 +1333,7 @@ class NotebookApp(JupyterApp):
|
||||
finally:
|
||||
self.remove_server_info_file()
|
||||
self.cleanup_kernels()
|
||||
|
||||
|
||||
def stop(self):
|
||||
def _stop():
|
||||
self.http_server.stop()
|
||||
|
Loading…
Reference in New Issue
Block a user