spec-first / connexion

Connexion is a modern Python web framework that makes spec-first and api-first development easy.
https://connexion.readthedocs.io/en/latest/
Apache License 2.0
4.48k stars 762 forks source link

Consider having a pluggable Security mechanism (OAuth2, Basic Auth, ..) #124

Closed hjacobs closed 5 years ago

hjacobs commented 8 years ago

Connexion only supports simple OAuth 2 Bearer token lookups right now, we might consider having a more pluggable (but simple) mechanism which supports defining custom authentication/authorization functions for OpenAPI/Swagger security requirements.

Please note that users always can add custom mechanisms by decorating their handler functions (see https://github.com/zalando/connexion/blob/master/examples/basicauth/app.py), i.e. Connexion should only provide the convenience "glue" between OpenAPI-Spec and own functions.

jmcs commented 8 years ago

I already thought it. This could be implemented with pkg_resources entrypoints.

trancee commented 8 years ago

@jmcs can you give an example on how to do that?

jmcs commented 8 years ago

You can see how I did it in turnstile, you can add entry points in the setup.py.

trancee commented 8 years ago

I am sorry, but I do not quite understand how I can use that in my case. I am rather new to this library and Python itself. Do you have some sort of guide to follow?

jmcs commented 8 years ago

I will implement the plugin system as soon as possible. When I'm done I'll provide an example on how to create a plugin.

KarimJedda commented 8 years ago

I don't know if it's relevant but i've added JWT as auth method for connexion, how can I share it?

rafaelcaricio commented 8 years ago

@KarimJedda Do you have it in a public repo where we could take a look?

dfeinzeig commented 8 years ago

@KarimJedda, I need JWT as an auth method too. can you share what you've done?

dfeinzeig commented 8 years ago

@jmcs , so you are suggesting that folks would write their custom security mechanism as a separate package? i will either be using or writing a JWT mechanism in the coming days, so if you have any suggestions I'm glad to think about them while working on this.

KarimJedda commented 8 years ago

@rafaelcaricio @dfeinzeig , I put an example up here https://github.com/KarimJedda/connexion_jwt_example , improve it and hack it and let's make a plug and play thing with it :dancer:

dfeinzeig commented 8 years ago

@KarimJedda , thank you! Looks like the flask-jwt package assumes that the flask app is also the source of issuing JWTs. A common case is using another service to issue JWTs, and using a flask/swagger-based service that does something, but using JWTs for auth. This is my need and the path I'm headed down now. I'll keep digging in and post PR when I have something and we can discuss it further then.

hjacobs commented 8 years ago

@dfeinzeig you can also check our Plan B Token Info service which validates JWTs issued by Plan B Provider and provides a "traditional" OAuth Token Info endpoint: https://github.com/zalando/planb-tokeninfo

The problem with validating self-contained JWTs directly is not having any revocation mechanism, Plan B Token Info provides that (checking tokens against revocation lists).

dfeinzeig commented 8 years ago

I'll take a look at that, thanks.

I believe it's fairly common to have relatively short expirations on JWTs, in our case 30 minutes, so there isn't really a need to revoke a token, since it's going to expire soon. Let me think about this some more though.

On Thu, Mar 17, 2016 at 11:44 AM, Henning Jacobs notifications@github.com wrote:

@dfeinzeig https://github.com/dfeinzeig you can also check our Plan B Token Info service which validates JWT (issued by Plan B Provider) and provides a "traditional" OAuth Token Info: https://github.com/zalando/planb-tokeninfo

The problem with validating self-contained JWTs directly is not having any revocation mechanism, Plan B Token Info provides that (checking tokens against revocation lists).

— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/zalando/connexion/issues/124#issuecomment-197939904

David Feinzeig feinzeig@gmail.com 508.353.4735

Site: http://david.feinzeig.com Blog: http://david.feinzeig.com/blog

woutervh commented 8 years ago

For my use-case the example of @KarimJedda is perfect,

in my swagger.yml I have:

securityDefinitions:
    jwt:
        type: apiKey
        name: Authorization
        in: header

however to make it work with flask-jwt, you need to customize swagger-ui/index.html

  // var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("api_key", key, "query");
  // window.swaggerUi.api.clientAuthorizations.add("api_key", apiKeyAuth);

   var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("Authorization", "JWT " + key, "header" );
   window.swaggerUi.api.clientAuthorizations.add( "jwt", apiKeyAuth );

there is currently no clean way to make this customisation.

LappleApple commented 8 years ago

@jmcs @rafaelcaricio @hjacobs Hi colleagues, wondering what you might want to do with this open issue. Looks like the previous commenter didn't get a direct response, at least not here?

advance512 commented 7 years ago

Doing this by looking at @KarimJedda's example proved super easy, even more with flask-jwt-extended which is a great library.

However, the fact that I have to constantly add Bearer in the Authorize dialog, combined with the rather bad UI design, the reloading of the page, etc - means that the experience isn't very comfortable. @WouterVH's hack helps a bit, but it is obviously not an option if you want to be based on the latest version of connexion and not your own fork (or even worse, editing files as part of your build process).

Using JWT seems like a very common scenario, as are various non-Basic authentication schemes that use the Bearer authentication scheme as basis. A vendor-specific setting, x-authentication-scheme, in the security scheme might suffice:

securityDefinitions:
  jwt:
    type: apiKey
    name: Authorization
    in: header
    x-authentication-scheme: Bearer

What do you think?

hjacobs commented 7 years ago

@advance512 I'll have to look at flask-jwt-extended, but supporting JWT is definitely interesting (we are also using it).

advance512 commented 7 years ago

I'll try and set up a PR.

KarimJedda commented 7 years ago

That would be fantastic! Right now we're using it at work to expose several machine learning models. The authentication is everytime a pain to setup. Especially when you're dealing with token refreshes and similar stuff. The solution i proposed is rather hacky and it requires doing @WouterVH's trick for the UI part. I'm sure the development would be more streamlined if it were integrated by default.

advance512 commented 7 years ago

FYI, I created pull request #390 adding support for x-authentication-scheme.

advance512 commented 6 years ago

Can we merge the PR in?

dtkav commented 5 years ago

Closing this because connexion 2.0 has support for the auth methods in the openapi3 spec, with pluggable auth/scope handler functions. Awesome work by @cziebuhr and @krise3k !