don't check origin on token-authenticated requests

adds LoginHandler.should_check_origin classmethod API
Min RK 10 years ago
parent 910caf56e1
commit 1e070a50f5

@ -114,6 +114,18 @@ class LoginHandler(IPythonHandler):
user_token = m.group(1)
return user_token
@classmethod
def should_check_origin(cls, handler):
"""Should the Handler check for CORS origin validation?
Origin check should be skipped for token-authenticated requests.
"""
if getattr(handler, '_user_id', None) is None:
# ensure get_user has been called, so we know if we're token-authenticated
handler.get_current_user()
token_authenticated = getattr(handler, '_token_authenticated', False)
return not token_authenticated
@classmethod
def get_user(cls, handler):
"""Called by handlers.get_current_user for identifying the current user.
@ -137,17 +149,23 @@ class LoginHandler(IPythonHandler):
# check login token from URL argument or Authorization header
user_token = cls.get_user_token(handler)
one_time_token = handler.one_time_token
authenticated = False
if user_token == token:
# token-authenticated, set the login cookie
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
authenticated = True
elif 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)
authenticated = True
if authenticated:
user_id = uuid.uuid4().hex
cls.set_login_cookie(handler, user_id)
# Record that we've been authenticated with a token.
# Used in should_check_origin above.
handler._token_authenticated = True
# cache value for future retrievals on the same request
handler._user_id = user_id
return user_id

@ -79,6 +79,16 @@ class AuthenticatedHandler(web.RequestHandler):
return 'anonymous'
return self.login_handler.get_user(self)
def skip_check_origin(self):
"""Ask my login_handler if I should skip the origin_check
For example: in the default LoginHandler, if a request is token-authenticated,
origin checking should be skipped.
"""
if self.login_handler is None or not hasattr(self.login_handler, 'should_check_origin'):
return False
return not self.login_handler.should_check_origin(self)
@property
def cookie_name(self):
default_cookie_name = non_alphanum.sub('-', 'username-{}'.format(
@ -267,8 +277,9 @@ class IPythonHandler(AuthenticatedHandler):
Copied from WebSocket with changes:
- allow unspecified host/origin (e.g. scripts)
- allow token-authenticated requests
"""
if self.allow_origin == '*':
if self.allow_origin == '*' or self.skip_check_origin():
return True
host = self.request.headers.get("Host")

@ -126,7 +126,9 @@ class WebSocketMixin(object):
Tornado >= 4 calls this method automatically, raising 403 if it returns False.
"""
if self.allow_origin == '*':
if self.allow_origin == '*' or (
hasattr(self, 'skip_check_origin') and self.skip_check_origin()):
return True
host = self.request.headers.get("Host")

Loading…
Cancel
Save