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 761 forks source link

Allow fast fail when mutliple security handlers are provided #1767

Open sami-sweng opened 11 months ago

sami-sweng commented 11 months ago

Description

When multiple security handlers are provided, for instance

security:
- api_key: []
- {}
components:
  securitySchemes:
    api_key:
      type: apiKey
      name: X-Auth
      in: header
      x-apikeyInfoFunc: app.apikey_auth

To allow either a token or a non authenticated request, assuming a token is provided, but for instance has a wrong signature, or is expired, it should be possible to reject the request.

Expected behaviour

There should be a mechanism to reject the request without looking for the next provider.

For instance raising an OAuthProblem or returning some specific value.

Actual behaviour

The request is considered non-authenticated and the incorrect token is ignored.

Steps to reproduce

Additional info:

Output of the commands:

Python 3.10.12
Version: 2.14.2
RobbeSneyders commented 11 months ago

Thanks @sami-sweng. Looking at the OpenAPI specification, the behavior you suggest makes sense.

The most straightforward way to achieve this behavior would be to fail anytime an authorization header or query parameter is provided for a non-authenticated scheme. Not sure if this behavior matches the OpenAPI spec though.

RobbeSneyders commented 11 months ago

Looks like it's unclear what the behavior should be: https://github.com/OAI/OpenAPI-Specification/issues/1698

RobbeSneyders commented 11 months ago

Opened an issue on the OpenAPI-specification repository to ask for clarification: https://github.com/OAI/OpenAPI-Specification/issues/3426

sami-sweng commented 10 months ago

Hi @RobbeSneyders Thank you for the reply and for the follow up.

I agree with the sentiment. I was of the idea that the current behavior is actually a good default. The idea was more to add a way to let the user implement this. When implementing the provider there should be a special value that when returned, would let the lib know that it encountered a fatal error and should not continue. (Or that could be a specific Exception).

I looked at the code and between the v2 and v3 it wasn't clear for me if that would still make sense in the v3, and if so where and how that could be implemented. That's why I didn't open a PR.