-
-
Notifications
You must be signed in to change notification settings - Fork 769
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
Conversation
examples/openapi3/jwt/app.py
Outdated
from jose import JWTError, jwt | ||
|
||
JWT_ISSUER = 'com.zalando.connexion' | ||
JWT_SECRET = '872f65270a71ca913766335276fb2c1b76b8ccdef749cdfc9a1598ac36d77c99' |
There was a problem hiding this comment.
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.
examples/openapi3/jwt/app.py
Outdated
try: | ||
return jwt.decode(token, JWT_SECRET, algorithms=[JWT_ALGORITHM]) | ||
except JWTError as e: | ||
raise Unauthorized from e |
There was a problem hiding this comment.
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(...)
There was a problem hiding this comment.
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 :)
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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
great work! I had a few minor comments, but otherwise this is looking really good :) |
@dtkav I have fixed the issues. |
Thanks @krise3k
Good call, I'm happy to fix the helloworld example in a separate diff.
…On Sat, Oct 27, 2018, 4:37 PM krise3k ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In examples/openapi3/jwt/app.py
<#732 (comment)>:
> + timestamp = _current_timestamp()
+ payload = {
+ "iss": JWT_ISSUER,
+ "iat": int(timestamp),
+ "exp": int(timestamp + JWT_LIFETIME_SECONDS),
+ "sub": str(user_id),
+ }
+
+ return jwt.encode(payload, JWT_SECRET, algorithm=JWT_ALGORITHM)
+
+
+def decode_token(token):
+ try:
+ return jwt.decode(token, JWT_SECRET, algorithms=[JWT_ALGORITHM])
+ except JWTError as e:
+ raise Unauthorized from e
I have made it python 2.7 compatible.
But it looks like helloworld example
<https://github.com/zalando/connexion/blob/dev-2.0/examples/openapi3/helloworld/hello.py>
is also broken on 2.7
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#732 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAlPSTybvfh5EV27pI4rnD_Zkx_5mq1pks5upO47gaJpZM4X7TdC>
.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work @krise3k !
@jmcs do you want to take a look as well, or are you happy for me to merge this? |
connexion/decorators/security.py
Outdated
try: | ||
auth_type, token = authorization.split(None, 1) | ||
except ValueError: | ||
raise OAuthProblem(description='Invalid authorization header') |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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).
Not sure if I missed something. Isn't this the same as oauth2 with |
@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. |
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? |
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. |
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. |
@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 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. |
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? |
I'm fine now. |
@dtkav indeed, rebase was not so obvious. It was easier to start from current master and cherry pick the commits, I also squash them. |
Great - thanks @krise3k and sorry about that. |
Can you expand the documentation and add doctstrings to the new functions? |
Hey @krise3k - do you think you'll have time to update the docs? |
@dtkav I will do it this weekend |
👍 |
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? |
@zout it's because I didn't need to use scopes, also I wanted to make this example as simple as possible. |
@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. |
@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. |
@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... |
Fixes #389, #607 .
Changes proposed in this pull request:
x-authentication-scheme=bearer
in apiKey method.scheme=bearer
in http methodx-bearerInfoFunc
in security definition orBEARERINFO_FUNC
env variable to pass a reference to token validation function