Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Websocket auth with token as query param #234

Merged
merged 8 commits into from
Mar 23, 2017
Merged

Websocket auth with token as query param #234

merged 8 commits into from
Mar 23, 2017

Conversation

rolweber
Copy link
Contributor

@rolweber rolweber commented Mar 8, 2017

Fixes #233 for version 2.0:

  • unit tests for auth mixin
  • code changes to auth mixin
  • updated swagger
  • fixed swagger link in docs

@rolweber
Copy link
Contributor Author

rolweber commented Mar 8, 2017

I used unittest.mock, which is a Python 3 feature.
There's a backport to Python 2.7, but it uses a different package name.

@parente
Copy link
Contributor

parente commented Mar 8, 2017

Thanks for submitting this @rolweber. I'll have a pass through it soon.

@minrk informed me yesterday that there is a long-term token capability in notebook 4.3+, not just the one time use token I noted in #211. I'm not sure if you found that or implemented your own (I haven't looked at the PR in depth yet), but it's something we should use if we can.

@rolweber
Copy link
Contributor Author

rolweber commented Mar 8, 2017

@parente: Thanks.

My PR doesn't generate tokens, it just verifies them. The difference is that it not only looks at the Authorization header, but also at query params. The token still has to be configured via KG_AUTH_TOKEN or similar.

@@ -54,8 +55,14 @@ def prepare(self):
"""
server_token = self.settings.get('kg_auth_token')
if server_token:
client_token = self.request.headers.get('Authorization')
if client_token != 'token %s' % server_token:
client_token = self.get_argument('token', '')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably default to None, not empty string.

if client_token == '':
client_token = self.request.headers.get('Authorization')
if client_token and client_token.startswith('token '):
client_token = client_token[len('token '):]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

len('token ') should probably be computed once and stored a global in this module to avoid recompute it on every request.

from kernel_gateway.mixins import JSONErrorsMixin
from kernel_gateway.mixins import TokenAuthorizationMixin, JSONErrorsMixin

class SuperTokenAuthHandler(object):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason for defining this class just to have a prepare() instead of implementing prepare in TestableTokenAuthHandler which is the only subclass?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to put it in a base class, because the tested method from the mixin calls super.prepare() in the good case. Maybe there's a more elegant way to do it, I still have to familiarize myself with Python.

@parente
Copy link
Contributor

parente commented Mar 11, 2017

My PR doesn't generate tokens, it just verifies them. The difference is that it not only looks at the Authorization header, but also at query params.

@rolweber after reading through the jupyter/notebook master code, I still think the code in KG for generating and verifying tokens, plus the code in the PR here for checking query parameters for tokens, is redundant. https://github.com/jupyter/notebook/blob/68a514a29d0e79af66ce6dd75c87e991fb58126d/notebook/auth/login.py#L148, which feeds all of the handlers.get_current_user now supports tokens both in Authorization headers and token query parameters. Moreover, it's used on all endpoints by default including the Websocket endpoint. In the end, I think we want less code in the KG and to rely on as much of the code in notebook as possible.

@rolweber
Copy link
Contributor Author

@parente: You're probably right, but that's what issue #211 is about. I opened issue #234 with a smaller scope, because I'm trying to find my way into a code base I'm not familiar with, in a programming language I'm not familiar with. Issue #211 is simply out of my league at the moment.

I'll update the PR with your suggested improvements some time this week.

@parente
Copy link
Contributor

parente commented Mar 14, 2017

@rolweber Don't get me wrong: My notes above aren't meant to preclude merging this and then iterating on how to switch to what's in notebook server over time. I appreciate the PR you put together!

@rolweber
Copy link
Contributor Author

@parente: Thanks. The code is updated now.

@rolweber
Copy link
Contributor Author

ping?

client_token = self.get_argument('token', '')
if client_token == '':
client_token = self.get_argument('token', None)
if client_token == None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if client_token is None:

@parente
Copy link
Contributor

parente commented Mar 23, 2017

@rolweber Missed the update from 7 days ago. Thanks for the ping. I had just one further piece of feedback, then we can merge.

@rolweber
Copy link
Contributor Author

@parente: Thanks! I'll try to find time for backporting this change to 1.2.x tomorrow.

@parente parente merged commit 737c22f into jupyter-server:master Mar 23, 2017
@parente
Copy link
Contributor

parente commented Mar 23, 2017

@rolweber In it goes! 🍰

Would you like to be added as a maintainer to this repo so that you can help review and merge PRs as well?

@rolweber
Copy link
Contributor Author

@parente: Great! It's been a while since I could last contribute to somebody else's OSS project :-)

Yes, it would be cool if I could become a maintainer here.

@parente
Copy link
Contributor

parente commented Mar 23, 2017

Whelp, it's your project now too. Welcome to the 🎉 .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support token auth via query parameter
2 participants