i get this error on swagger editor when using the auth0
Schema error at securityDefinitions.auth0
is not exactly one from <#/definitions/basicAuthenticationSecurity>,<#/definitions/apiKeySecurity>,<#/definitions/oauth2ImplicitSecurity>,<#/definitions/oauth2PasswordSecurity>,<#/definitions/oauth2ApplicationSecurity>,<#/definitions/oauth2AccessCodeSecurity>
Jump to line 67
where my .yaml file is like:
securityDefinitions:
auth0:
type: oauth2
authorizationUrl: https://domain.auth0.com/authorize
flow: implicit
tokenName: id_token
scopes:
openid: Grant access to user
apiKey:
type: apiKey
name: api-key
in: query
apiKey1:
type: apiKey
name: api-key
in: header
what am i missing?
Remove tokenName - it's not a supported field.
Check the specification to see which fields are allowed in securityDefinitions:
https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#securitySchemeObject
Related
I want to specify the default value of a Bearer token for authentication in the Swagger Editor. Is it possible?
securitySchemes:
Bearer:
type: apiKey
name: Authorization
in: header
description: Enter your bearer token in the format **Bearer <token>**
security:
- Bearer: []
Describing the problem
I was struggeling the last few days to figure out how to use apikey security in openapi, swagger, connexion for role based token authentication. The following OpenAPI 3.0 endpoint definition:
/lab/samples/list:
get:
tags:
- lab
summary: get a list of all registered samples
operationId: list_samples
responses:
"200":
description: successfully returned all available samples and their notification status
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Sample-For-Lab'
x-content-type: application/json
"400":
description: invalid request
content:
application/json:
schema:
$ref: '#/components/schemas/inline_response'
security:
- bearerAuth: ['labuser']
with the corresponding security definition
securitySchemes:
bearerAuth:
type: apiKey
name: Authorization
in: header
x-apikeyInfoFunc: swagger_server.controllers.authorization_controller.check_bearerAuth
So far so good. I built the corresponding server stubs using swagger-codegen, which follow the connexion security model and provide two fields api_key i.e. the bearer token and 'required_scopes' i.e. which should contain 'labuser'. When accessing the endpoint, the controller function is called:
def check_adminuserAuth(api_key, required_scopes):
return {'sample_key' : 'sample_value}
While the bearer token is properly passed, required_scopes is None. So there's no way of actually validating if credentials and permissions shown in the provided token actually match the endpoint's required scope of labuser in the authorization controller. I thought about handling validation in the called endpoints list_systemusers() but the token is no passed on by connexion.
Not supported in OpenAPI 3.0
After doing some digging, I found out that OpenAPI 3.0 provides apiKey validation on a global API level (i.e. authenticated or not), but does not offer support for individual scopes per endpoint. If you want individual scopes, you need to switch to OAuth security. However support for security scopes through apiKey security is coming in OpenAPI 3.1
Workaround
So for now the only way of making bearer token security with individual scopes work, is to actually define a security scheme for every scope e.g.
securitySchemes:
adminuserAuth:
type: apiKey
description: Provide your bearer token in the format **Bearer <token>**
name: Authorization
in: header
x-apikeyInfoFunc: swagger_server.controllers.authorization_controller.check_adminuserAuth
statsuserAuth:
type: apiKey
description: Provide your bearer token in the format **Bearer <token>**
name: Authorization
in: header
x-apikeyInfoFunc: swagger_server.controllers.authorization_controller.check_statsuserAuth
labuserAuth:
type: apiKey
description: Provide your bearer token in the format **Bearer <token>**
name: Authorization
in: header
x-apikeyInfoFunc: swagger_server.controllers.authorization_controller.check_labuserAuth
and on the path definition then add your required security authentication schemes
security:
- labuserAuth: []
- adminuserAuth: []
x-openapi-router-controller: swagger_server.controllers.lab_controller
Now I know by which authorization controller method is called the required scope a user needs to show and therefore can validate it against the ones shown in the token.
Running latest (and now old due to the switchover to flask REST-X) flask RESTPlus using the authorization functionality for the swagger interface with a Bearer token as follows:
authorizations = {
'apikey': {
'type': 'apiKey',
'in': 'header',
'name': 'Bearer '
}
But although the "Authorise" box comes up in the swagger interface, and I can put a token in there, it doesn't get added to the requests coming out or the curl format that swagger provides, so we can see clearly it's not being picked up. What's going on here and how do I fix it?
Make sure the code also has annotations that would add security to individual operations or globally. This is needed to actually attach the Authorization header to operations.
In other words, the generated OpenAPI definition should contain the following.
If using OpenAPI 2.0:
swagger: '2.0'
securityDefinitions:
apikey:
type: apiKey
in: header
name: Authorization
security:
- apiKey: []
If using OpenAPI 3.0:
openapi: 3.0.0
components:
securitySchemes:
apikey:
type: apiKey
in: header
name: Authorization
# or using OAS3 Bearer auth scheme
# apiKey:
# type: http
# scheme: bearer
security:
- apiKey: []
I have the following spec.yaml file
swagger: '2.0'
info:
title: Store API
version: "0.3.5"
host: SELF_URL_REPLACED_BY_APP
schemes:
- https
basePath: /
produces:
- application/json
tags:
- name: account
- name: transcripts
security:
- auth0:
- openid
- apiKey: []
securityDefinitions:
auth0:
type: oauth2
authorizationUrl: https://store.auth0.com/authorize
flow: implicit
tokenName: id_token
scopes:
openid: Grant access to user
apiKey:
type: apiKey
name: Authorization
in: header
I get this error when i try to validate it in http://editor.swagger.io/:
✖ Swagger Error
Not a valid securityDefinitions definition
Jump to line 19
Details
Object
code: "ONE_OF_MISSING"
params: Array [0]
message: "Not a valid securityDefinitions definition"
path: Array [2]
schemaId: "http://swagger.io/v2/schema.json#"
inner: Array [6]
level: 900
type: "Swagger Error"
description: "Not a valid securityDefinitions definition"
lineNumber: 19
What am I missing? I am able to login using Auth0 and everything seems to work fine.
Any advice is much appreciated.
tokenName is not a valid property of the SecurityDefinitions object.
However your Swagger definition has other errors - such as no paths - which may cause it to give incorrect validation errors about securityDefinitions as you're editing.
The following for instance should validate fine:
swagger: '2.0'
info:
title: Store API
version: "0.3.5"
host: SELF_URL_REPLACED_BY_APP
schemes:
- https
basePath: /
produces:
- application/json
tags:
- name: account
- name: transcripts
paths:
/pets:
get:
description: Returns all pets from the system that the user has access to
produces:
- application/json
responses:
'200':
description: A list of pets.
schema:
type: array
items:
type: string
security:
- auth0:
- openid
- apiKey: []
securityDefinitions:
auth0:
type: oauth2
authorizationUrl: https://store.auth0.com/authorize
flow: implicit
scopes:
openid: Grant access to user
apiKey:
type: apiKey
name: Authorization
in: header
Also the security section does not belong at the top level, but should be placed under each API method (see above definition for an example) to specify which security definitions should be applied to that API.
Is it possible to have same path appear more than once in one API spec which is being rendered by Swagger-UI?
Should I create separate api specs and load two instances of Swagger-UI? What is the best way to handle this?
For ex. I have endpoint called /oauth/token which I want to document with one set of parameters for OAuth Authorization Code flow and the same endpoint /oauth/token documents for client_credentials flow with different set of parameters.
/oauth/token:
post:
summary: token endpoint for authorization_code flow
parameters:
- name: code
type: string
description: Required for Authorization Code Flow
in: formData
required: true
- name: grant_type
type: string
description: Grant Type should be specified as authorization_code
in: formData
required: true
default: authorization_code
enum:
- authorization_code
- client_credentials
- name: client_id
type: string
description: Consumer Key
in: formData
required: true
- name: client_secret
type: string
description: Consumer Secret
in: formData
required: true
- name: endOtherSessions
in: formData
type: boolean
required: false
default: false
description: Optional parameter. Default is false - do not allow concurrent login. Send true to end any other user sessions.
tags:
- OAuth2 Authorization Code
Same endpoint for client_credentials flow
/oauth/token2:
post:
summary: token for client credentials
parameters:
- name: grant_type
type: string
description: Grant Type should be specified as client_credentials
in: formData
required: true
default: client_credentials
enum:
- authorization_code
- client_credentials
- name: client_id
type: string
description: Consumer Key
in: formData
required: true
- name: client_secret
type: string
description: Consumer Secret
in: formData
required: true
tags:
- OAuth2 Client Credentials
Since the question is about OAuth2 rather than a single endpoint with different parameters, then the solution is actually different.
Swagger has a specific way to document authorization methods, including the 4 common OAuth2 flows.
These are described using the Security Definitions Object which is located at the top Swagger object.
Within it, you can define one or more OAuth2 flows. The spec itself provides a sample for the implicit flow, but others follow a similar structure. The difference is by which fields are provided, namely authorizationUrl and tokenUrl (depending on the flow type).
Once you have that, you can specify which security schemes are required. You can specify it for all the operations at the Swagger object or at the Operation level.
The spec allows you to define that a set of security methods are required together, or that the user can choose between given sets.