Security¶
Connexion implements a pluggable security validation mechanism and provides built-in support for some of the most popular security schemes.
Swagger 2 |
Connexion support |
---|---|
Basic Authentication |
✅ |
API key |
✅ |
Oauth2 |
✅ |
OpenAPI |
|
HTTP Basic |
✅ |
HTTP Bearer |
✅ |
Other HTTP schemes (RFC 7253) |
No built-in support, use a custom security handler |
API key |
✅ |
Oauth2 |
✅ |
OpenID |
No built-in support, use a custom security handler |
General authentication flow¶
For each supported authentication type, Connexion lets you register a validation function to validate the incoming credentials, and return information about the authenticated user.
The validation function must either be defined in the API security definition
as x-{type}InfoFunc
, or in the environment variables as {TYPE}INFO_FUNC
. The function
should be referenced as a string using the same syntax that is used to connect an operationId
to a Python function when routing.
While the validation functions should accept different arguments based on the authentication type (as documented below), they should all return a dict which complies with RFC 7662:
{
"active": true,
"client_id": "l238j323ds-23ij4",
"username": "jdoe",
"scope": "read write dolphin",
"sub": "Z5O3upPC88QrAjx00dis",
"aud": "https://protected.example.net/resource",
"iss": "https://server.example.com/",
"exp": 1419356238,
"iat": 1419350238,
"extension_field": "twenty-seven"
}
The token information is made available to your endpoint view functions via the context, which you can also have passed in as an argument.
Note
Note that you are responsible to validate any fields other than the scopes yourself.
Basic Authentication¶
For Basic authentication, the API security definition must include an
x-basicInfoFunc
definition or set the BASICINFO_FUNC
environment variable.
The function should accept the following arguments:
username
password
required_scopes (optional)
request (optional)
You can find a minimal Basic Auth example application in Connexion’s “examples” folder.
Bearer Authentication (JWT)¶
For Bearer authentication (JWT), the API security definition must include an
x-bearerInfoFunc
definition or set the BEARERINFO_FUNC
environment variable.
The function should accept the following arguments:
token
required_scopes (optional)
request (optional)
You can find a minimal Bearer example application in Connexion’s “examples” folder.
ApiKey Authentication¶
For API key authentication, the API security definition must include an
x-apikeyInfoFunc
definition or set the APIKEYINFO_FUNC
environment variable.
The function should accept the following arguments:
apikey
required_scopes (optional)
request (optional)
You can find a minimal API Key example application in Connexion’s “examples” folder.
Multiple Authentication Schemes¶
With Connexion, it is also possible to combine multiple authentication schemes
as described in the OpenAPI specification. When multiple authentication
schemes are combined using logical AND, the token_info
argument will
consist of a dictionary mapping the names of the security scheme to their
corresponding token_info
.
Multiple OAuth2 security schemes in AND fashion are not supported.
Custom security handlers¶
You can implement your own security handlers for schemes that are not supported yet in Connexion
by subclassing the connexion.security.AbstractSecurityHandler
class and passing it in a custom
security_map
to your application or API:
from connexion.security import AbstractSecurityHandler
class MyCustomSecurityHandler(AbstractSecurityHandler):
security_definition_key = "x-{type}InfoFunc"
environ_key = "{TYPE}INFO_FUNC"
def _get_verify_func(self, {type}_info_func):
...
security_map = {
"{type}": MyCustomSecurityHandler,
}
from connexion import AsyncApp
app = AsyncApp(__name__, security_map=security_map)
app.add_api("openapi.yaml", security_map=security_map)
from connexion import FlaskApp
app = FlaskApp(__name__, security_map=security_map)
app.add_api("openapi.yaml", security_map=security_map)
from asgi_framework import App
from connexion import ConnexionMiddleware
app = App(__name__)
app = ConnexionMiddleware(app, security_map=security_map)
app.add_api("openapi.yaml", security_map=security_map)
Note
If you implement a custom security handler, and think it would be valuable for other users, we would appreciate it as a contribution.