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

Add support for JWT authentication #732

Merged
merged 7 commits into from
Nov 12, 2018
Merged

Conversation

krzysztof-indyk
Copy link
Contributor

Fixes #389, #607 .

Changes proposed in this pull request:

  • For swagger 2.0 add support for x-authentication-scheme=bearer in apiKey method.
  • For OpenAPI 3.0 add support for scheme=bearer in http method
  • Use x-bearerInfoFunc in security definition or BEARERINFO_FUNC env variable to pass a reference to token validation function

@jmcs jmcs mentioned this pull request Oct 26, 2018
from jose import JWTError, jwt

JWT_ISSUER = 'com.zalando.connexion'
JWT_SECRET = '872f65270a71ca913766335276fb2c1b76b8ccdef749cdfc9a1598ac36d77c99'
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you make this something like not_really_secret? I can imagine some poor security engineer thinking these are leaked creds.

try:
return jwt.decode(token, JWT_SECRET, algorithms=[JWT_ALGORITHM])
except JWTError as e:
raise Unauthorized from e
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think raise ... from is python 2.7 compatible.
You probably need to use six.raise_from(...)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@dtkav It's not supposed to run on 2.7, please look at shebang.
BTW end of python 2.7 is coming :)

Copy link
Collaborator

Choose a reason for hiding this comment

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

It's not a matter of my personal preference (I'm also on python 3). Connexion explicitly supports python 2.7, so I think making the examples backwards compatible is the right thing to do.

If you don't want to do it, I'm happy to. I'd prefer to follow the rule of least surprise now, because otherwise I'll have to respond to a ticket about this example being "broken" later.

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 have made it python 2.7 compatible.

But it looks like helloworld example is also broken on 2.7

type: http
scheme: bearer
bearerFormat: JWT
x-bearerInfoFunc: fakeapi.hello.jwt_info
Copy link
Collaborator

Choose a reason for hiding this comment

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

github is complaining about missing newline at end of file

@dtkav
Copy link
Collaborator

dtkav commented Oct 27, 2018

great work! I had a few minor comments, but otherwise this is looking really good :)

@krzysztof-indyk
Copy link
Contributor Author

@dtkav I have fixed the issues.

@dtkav
Copy link
Collaborator

dtkav commented Oct 28, 2018 via email

@spec-first spec-first deleted a comment Oct 28, 2018
Copy link
Collaborator

@dtkav dtkav left a comment

Choose a reason for hiding this comment

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

Nice work @krise3k !

@dtkav
Copy link
Collaborator

dtkav commented Oct 28, 2018

@jmcs do you want to take a look as well, or are you happy for me to merge this?

@dtkav dtkav requested a review from jmcs October 28, 2018 19:17
try:
auth_type, token = authorization.split(None, 1)
except ValueError:
raise OAuthProblem(description='Invalid authorization header')

Choose a reason for hiding this comment

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

Is OAuthProblem class appropriate here? The code seems more generic and not only about OAuth

Copy link
Contributor

Choose a reason for hiding this comment

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

Previously connexion only supported oauth. It's more generic now. We could rename the Exception, but it would be backward incompatible if someone has set up a custom error_handler.

Copy link
Collaborator

Choose a reason for hiding this comment

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

You could also inherit from OAuthProblem in order to rename it and keep it backwards compatible. (and leave a note to change this on the next major version bump).

@cziebuhr
Copy link
Contributor

cziebuhr commented Oct 29, 2018

Not sure if I missed something. Isn't this the same as oauth2 with x-tokenInfoFunc set to decode_token and an empty scope?

@krzysztof-indyk
Copy link
Contributor Author

@cziebuhr When I have implemented JWT I found that verify function is a closure and guessed that it would be hard to avoid code duplication.
Today I take a second look at the code and extract common function to verify oauth and bearer tokens.

@spec-first spec-first deleted a comment Nov 1, 2018
@cziebuhr
Copy link
Contributor

cziebuhr commented Nov 1, 2018

Looks better now, but I still don't get the difference. IMHO the only difference is, that scope is not validated. Can't you achieve the same result when specifying oauth2 as type of the security scheme and an empty array as scope for security requirement?

@dtkav
Copy link
Collaborator

dtkav commented Nov 5, 2018

I'm a bit out of the loop on this one, but It seems valuable to be able to define the correct security scheme in the spec, and not have to make everything work through oauth2. In addition, there may be a use case for someone supporting multiple security schemes, so they may need a handler for each one.
@cziebuhr thoughts?

@cziebuhr
Copy link
Contributor

cziebuhr commented Nov 5, 2018

One can't configure bearer method and oauth2 together, because if the first validator finds an Authorization header of type Bearer and can't validate its value, it will fail hard and not continue with the next validator.

@dtkav
Copy link
Collaborator

dtkav commented Nov 6, 2018

@cziebuhr I'm not sure if you have blocking feedback for the PR, and if so how @krise3k can address your feedback.

I now get your point about oauth2 and http:bearer both using the Bearer keyword in the header. Thanks for clarifying that.

Still, the 3.x.x spec [0] supports http:bearer, so it seems wise to support it as well, even if it's just for the principle of least surprise (people wouldn't expect that they need to change auth methods in their spec to make auth work, even if they are similar/subsets/supersets).

AFAICT this diff adds support for the http:bearer options in the spec, and seems pretty DRY.

[0] https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#security-scheme-object

@dtkav dtkav changed the base branch from dev-2.0 to master November 6, 2018 00:29
@dtkav
Copy link
Collaborator

dtkav commented Nov 6, 2018

I tried to update this PR to be against master (as connexion 2.0 was released), but it didn't work as cleanly as I expected (sorry!). @krise3k do you mind rebasing your changes onto master?

@cziebuhr
Copy link
Contributor

cziebuhr commented Nov 6, 2018

@cziebuhr I'm not sure if you have blocking feedback for the PR, and if so how @krise3k can address your feedback.

I'm fine now.

@krzysztof-indyk
Copy link
Contributor Author

@dtkav indeed, rebase was not so obvious. It was easier to start from current master and cherry pick the commits, I also squash them.

@spec-first spec-first deleted a comment Nov 6, 2018
@dtkav
Copy link
Collaborator

dtkav commented Nov 7, 2018

Great - thanks @krise3k and sorry about that.
I think the last eyes are probably @jmcs then.

@jmcs
Copy link
Contributor

jmcs commented Nov 7, 2018

Can you expand the documentation and add doctstrings to the new functions?

@dtkav
Copy link
Collaborator

dtkav commented Nov 9, 2018

Hey @krise3k - do you think you'll have time to update the docs?
Let me know if I can help.

@krzysztof-indyk
Copy link
Contributor Author

@dtkav I will do it this weekend

@krzysztof-indyk
Copy link
Contributor Author

@jmcs, @dtkav I push the changes.

@spec-first spec-first deleted a comment Nov 11, 2018
@jmcs
Copy link
Contributor

jmcs commented Nov 12, 2018

👍

@jmcs jmcs merged commit 6ec1182 into spec-first:master Nov 12, 2018
@dtkav dtkav mentioned this pull request Dec 17, 2018
@zout
Copy link

zout commented Sep 16, 2019

Hi @krise3k,

We are using your JWT code, and it works great, many thanks for your work. However, we are using scopes in the JWT token payload. In your example code you have set a scope that does nothing. We would like to contribute code for scope checking. Is there any reason you have skipped this? And is there any particular problem with that that we need to solve?

@krzysztof-indyk
Copy link
Contributor Author

@zout it's because I didn't need to use scopes, also I wanted to make this example as simple as possible.

@bjoluc
Copy link

bjoluc commented Mar 24, 2020

@zout Do you still want to approach this? "Scope" (or should we say "claim"?) checking would be really helpful for us too. I can take a look at this otherwise.

@zout
Copy link

zout commented Mar 24, 2020

@bjoluc We have build it in our project now, but as separate functions that decode de JWT to check for scope in the handling function. I could give you that code. But it is quite challenging to get to the scopes that are listed in the yaml file. So we decided not to do that.

@bjoluc
Copy link

bjoluc commented Mar 24, 2020

@zout Thanks for the quick reply! Yeah, we ended up implementing a custom solution too. Just thought it would be really nice to support a claims validation function (would have saved me a lot of time). I will try to figure it out and mention you in the PR in case I succeed...

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.

Add support for x-authentication-scheme and Bearer auth scheme in apiKey security definition
7 participants