Nelmio 4 security definitions index not found - symfony

I try to configure nelmio/api-doc-bundle to use Authorization header for my Bearer token.
I configure it in nelmio_api_doc.yaml like this
nelmio_api_doc:
documentation:
info:
title: title
version: 1.0.0
securityDefinitions:
Bearer:
type: apiKey
description: 'jwt from oauth prefixed by `Bearer`'
name: Authorization
in: header
security:
- Bearer: []
areas: # to filter documented areas
path_patterns:
- ^/api(?!/doc$|/doc.json$) # Accepts routes under /api except /api/doc and /api/doc.json
But when i got to the ui doc page I got :
Notice: Undefined index: securityDefinitions
Did someone know how to fix it ?

It was changed in version 4, check this docs https://symfony.com/doc/4.x/bundles/NelmioApiDocBundle/index.html#using-the-bundle

Related

WSO2 APIM 4.1.0 (Linux) : REST API testing fails in Publisher : Invalid URL., RESOURCE = /xxxx HEALTH CHECK URL = xxxx

I'm trying to create a simple REST API with a mock back-end in the publisher and test it in the publisher itself, before publishing it to the Dev portal.
Swagger definition
openapi: 3.0.1
info:
title: TestAPI
version: '1.0'
servers:
- url: /
security:
- default: []
paths:
/getMessage:
get:
parameters: []
responses:
'200':
description: ok
security:
- default: []
x-auth-type: Application & Application User
x-throttling-tier: Unlimited
x-wso2-application-security:
security-types:
- oauth2
optional: false
components:
securitySchemes:
default:
type: oauth2
flows:
implicit:
authorizationUrl: 'https://test.com'
scopes: {}
x-wso2-auth-header: Authorization
x-wso2-cors:
corsConfigurationEnabled: false
accessControlAllowOrigins:
- '*'
accessControlAllowCredentials: false
accessControlAllowHeaders:
- authorization
- Access-Control-Allow-Origin
- Content-Type
- SOAPAction
- apikey
- Internal-Key
accessControlAllowMethods:
- GET
- PUT
- POST
- DELETE
- PATCH
- OPTIONS
x-wso2-production-endpoints:
urls:
- 'https://run.mocky.io/v3/64df2918-ea8d-4fc9-8e6e-1f57d8b07070'
type: http
x-wso2-sandbox-endpoints:
urls:
- 'https://run.mocky.io/v3/64df2918-ea8d-4fc9-8e6e-1f57d8b07070'
type: http
x-wso2-basePath: /test/1.0
x-wso2-transports:
- http
- https
x-wso2-response-cache:
enabled: false
cacheTimeoutInSeconds: 300
Request (generated from the "Test -> Try it out" section )
curl -X 'GET' \
'https://localhost:8243/test/1.0/getMessage' \
-H 'accept: */*' \
-H 'Internal-Key: [key]'
Response (from postman)
{
"code": "404",
"type": "Status report",
"message": "Not Found",
"description": "The requested resource is not available."
}
APIM Log
[2022-06-07 12:02:06,610] INFO - LogMediator STATUS = Message dispatched to the main sequence. Invalid URL., RESOURCE = /test/1.0/getMessage, HEALTH CHECK URL = /test/1.0/getMessage
NOTE: The sample "PizzaShack" API gets deployed correctly and works fine but when I try to create one from scratch it always gives the Invalid URL error. The request URL seems fine to me, what am I doing wrong ?

Enable CORS for Cloud Run with Cloud Endpoints v1

I have been following an article on Medium to deploy Cloud Endpoints v1 in front of a Cloud Run service hosting a REST API and everything works well.
I now have a requirement to enable CORS support and I've added the below configuration to my endpoints YAML file but get an error saying "This service does not allow CORS traffic" when my browser tries to make a pre-flight request (I've tested this with Postman too with the same error). I know there's a flag to enable CORS --cors_preset=basic using environment variables but I'm not sure what key to set with. Any ideas or help is appreciated.
Endpoints YAML snipper:
swagger: '2.0'
info:
title: Cloud Endpoints with Cloud Run
description: Testing Cloud Endpoints with Cloud Run
version: 1.0.0
host: endpoint-<hash>-uc.a.run.app
x-google-endpoints:
- name: endpoint-<hash>-uc.a.run.app
allowCors: true
schemes:
- https
produces:
- application/json
Error:
{
"code": 7,
"message": "The service does not allow CORS traffic.",
"details": [
{
"#type": "type.googleapis.com/google.rpc.DebugInfo",
"stackEntries": [],
"detail": "service_control"
}
]
}
PS: Thanks Guillaum Blaquiere for the awesome article.
UPDATE:
I ended up testing with an incomplete URL and hence received the above error as my backend service wasn't configured to respond to all pre-flight request URLs. Having fixed this, I now get the below error only on the CORS pre-flight configured URL.
{
"code": 13,
"message": "INTERNAL_SERVER_ERROR",
"details": [
{
"#type": "type.googleapis.com/google.rpc.DebugInfo",
"stackEntries": [
],
"detail": "application"
}
]
}
and logs:
invalid URL prefix in "", client: <CLIENT_IP>, server: , request: "OPTIONS /api/v1/<REMAINING_URL> HTTP/1.1", host: "endpoint-<HASH>-uc.a.run.app"
I would say it's necesary to add ESPv2 Config, I've noticed that the note regarding the ESPv2 config was added since last april, and the Medium document was published on 2019, so I think such required step was not mentioned before.
Later in the same section it's mentioned that the flags for cors are passed by the "--set-env-vars" flag of the deploy command.
You can find more about the ESPv2 Beta startup options in here.
I managed to resolve the issue by defining OPTIONS operations in my YAML file with no security, for each path that I had already defined. See below example YAML file for an endpoint path '/api/v1/hello' with GET and OPTIONS operations defined.
swagger: '2.0'
info:
title: Cloud Endpoints with Cloud Run
description: Testing Cloud Endpoints with Cloud Run
version: 1.0.0
host: endpoint-randomhash-uc.a.run.app
x-google-endpoints:
- name: endpoint-randomhash-uc.a.run.app
allowCors: true
schemes:
- https
produces:
- application/json
x-google-backend:
address: https://backend-randomhash-uc.a.run.app
path_translation: APPEND_PATH_TO_ADDRESS
security:
- auth0_jwk: []
paths:
/api/v1/hello:
get:
summary: Say hello
operationId: helloName
parameters:
- name: "name"
in: "query"
description: "Your name"
type: "string"
responses:
'200':
description: Successful operation
schema:
type: string
options:
summary: CORS pre-flight for say hello
operationId: helloNameOptions
parameters:
- name: "name"
in: "query"
description: "Your name"
type: "string"
responses:
'200':
description: Successful operation
schema:
type: string
security: []
securityDefinitions:
auth0_jwk:
authorizationUrl: ""
flow: "implicit"
type: "oauth2"
x-google-issuer: "https://project.auth0.com/"
x-google-jwks_uri: "https://project.auth0.com/.well-known/jwks.json"
x-google-audiences: "firebase-application-host"
As Sergio pointed out in his comment to a SO question, the other option in my case is to use Firebase Hosting proxy to use the same domain and avoid CORS.

There seems to be a mismatch between last deployed API and actually in-use API

According to Google Cloud Console > Endpoints > Services > Deployment History this is the currently deployed API spec:
swagger: "2.0"
info:
title: "JSON Ingester"
description: "Receive JSON files, transform and load them."
version: "1.0.0"
host: "project-id-123.appspot.com"
schemes:
- "https"
paths:
"/upload":
post:
summary: "ETL JSON file."
security:
- api_key: []
operationId: "upload"
consumes:
- multipart/form-data
parameters:
- in: formData
name: file
type: string
responses:
200:
description: "File uploaded."
schema:
type: string
400:
description: "Error during file upload."
securityDefinitions:
api_key:
type: "apiKey"
name: "apikey"
in: "query"
But the key "apikey" is not accepted - instead it requires "key" which was specified in an openapi.yaml that I deployed few hours ago.
This works while it shouldn't:
$ curl -X POST -F "file=#data/file_6.json" https://project-id-123.appspot.com/upload\?key\=AIzaS...Eaoog
And this doesn't work while it should:
$ curl -X POST -F "file=#data/file_6.json" https://project-id-123.appspot.com/upload\?apikey\=AIzaS...Eaoog
{
"code": 16,
"message": "Method doesn't allow unregistered callers (callers without established identity). Please use API Key or other form of API consumer identity to call this API.",
"details": [
{
"#type": "type.googleapis.com/google.rpc.DebugInfo",
"stackEntries": [],
"detail": "service_control"
}
]
}
Do I have to clear a cache or something?
For deploying the API I use:
gcloud endpoints services deploy "./openapi.yaml"
Any ideas?
What rollout_strategy did you use when you deploy ESP? If not specified, default is "fixed". You should use "managed"
Please also check the generated service config by CLI "gcloud endpoints configs describe". Check its system_parameters filed to see if your new "apikey" is created properly.

How to change default swagger.json file path?

I have created Ngnix-Consul Docker setup referred https://github.com/nginxinc/NGINX-Demos/tree/master/consul-template-demo.
And have created many microservices. So All the microservices are accessible only after adding the service name for e.g.
http://example.com/service_name/get_data
All is working fine then I wanted to add swagger for all microservices so tried with below snippet
I am able to access swagger ui by using
http://example.com/service_name/ui
But the problem is I am not able to load swagger.json in that ui as its trying to access swagger.json on below url
http://example.com/swagger.json
but the json file is on
http://example.com/service_name/swagger.json
How can I change the default path of swagger.json?
The applications in microservices are created in python-flask
I have tried below snippet
swagger: "2.0"
info:
description: "Add service"
version: "1.0.0"
title: "Add Service"
contact:
email: "abc#efg.com"
license:
name: "s1.0"
url: "http://sample.com"
host: "abc.efg.com"
tags:
- name: "add service"
description: "service"
- name: "delete service"
description: "data"
schemes:
- "http"
paths:
/service_name/get_data:
and even I have tried to add basePath in the swagger.yaml file
then It did not even open swaggerui
swagger: "2.0"
info:
description: "Add service"
version: "1.0.0"
title: "Add Service"
contact:
email: "abc#efg.com"
license:
name: "s1.0"
url: "http://sample.com"
host: "abc.efg.com"
basePath: "service_name"
tags:
- name: "add service"
description: "service"
- name: "delete service"
description: "data"
schemes:
- "http"
paths:
/get_data:
Update:
from flask import Flask
import connexion
app = Flask(__name__)
app = connexion.App(__name__)
app.add_api('swagger.yaml')
//apis
if __name__ == "__main__":
app.run(host='0.0.0.0', port=8090, debug=True)
Had similar problem myself. The solution for me was to disable path rewrite in the NGINX level, so that the microservice would receive the full url:
Before:
Request:
http://example.com/service_name/get_data
Service sees:
/get_data
After:
Request:
http://example.com/service_name/get_data
Service sees:
/service_name/get_data
Only then you can specify basePath as "service_name" in the swagger.yaml file:
swagger: "2.0"
info:
description: "Add service"
version: "1.0.0"
title: "Add Service"
host: "abc.efg.com"
basePath: "service_name"
If file swagger.json is static in NGINX config you can make alias rule like this:
location ^~ /swagger.json {
alias /path_to/swagger.json;
}

NelmioApiDoc v3 / Swagger - multiple API docs

NelmioApiDoc v2 allowed to use multiple views parameter so I can hide some endpoints and present them on different URL
https://symfony.com/doc/current/bundles/NelmioApiDocBundle/multiple-api-doc.html
Is it possible to do it in NelmioApiDoc v3 which is using Swagger?
I am using Symfony 3.3
What you are looking for seems to be called "Areas" now in NelmioApiDoc v3.
Thanks to this feature, you can define areas which will each generates a different documentation :
You just have to define those areas in your config.yml:
nelmio_api_doc:
areas:
default:
path_patterns: [ ^/api ]
custom:
path_patterns: [ ^/custom ]
another_custom:
path_patterns: [ ^/anothercustom ]
Then you need to update your routing.yml file:
app.swagger_ui:
path: /api/doc/{area}
methods: GET
defaults: { _controller: nelmio_api_doc.controller.swagger_ui, area: default }
You can read about it on this doc.

Resources