Can't pass security validation when using oapi validation middleware
I use this library on sever side, while on client side do manually since the client is for mobile platform.
This is my openapi spec : I follow openapi documentation to define security scheme
paths:
/admins:
get:
description: Get AdminList
security:
- bearerAuth: []
operationId: getAdminList
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
And in my request I put Authorization header on request
Authorization: Bearer ---random JWT token ----
But I always get 'Security requirements failed' from validation middleware (the JWT token was checked and valid) Am I missing something ?
PS: also it return http error 403, while above documentation recommending to return http 401 error for unauthorized request.
Not sure this helps.. but you define auth globally in components, and you are applying it to the endpoint. You don't need to apply it to the endpoint since you are defining it globally as well. Try removing the security from the /admins endpoint.
@kevinduffey
As fas as I understand from this documentation, global or per-operation(per-method) security, both require "securitySchemes" on components to define security schemes.
If we want to globaly security we put "security: " tag at same level as paths/component, for example:
paths:
/admins:
get:
...
components:
securitySchemes:
bearerAuth:
type: http
.....
security:
bearerAuth: []
if we want per-operation (per-method) security we put 'security:' under method name like I do
That sounds right.. but your first example you had it on the method.. though that should be valid too.
I'm seeing this error as well, with the global security set (not at the path level):
paths:
/models:
post:
...
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
security:
- bearerAuth: []
Removing the global security lets the validation pass:
curl -X POST "http://127.0.0.1:8090/models" -H "Authorization: Bearer a503faf9-45b5-4fec-8334-337284a66ea4" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"name\":\"string\",\"type\":\"string\",\"options\":\"string\",\"parentId\":\"string\"}"
I'm looking into the issue now, just wanted to make a note of it here for reference
@bandirsen I was able to resolve the issue by providing a custom validator function to the options, like so:
validatorOptions := &oapimiddleware.Options{}
validatorOptions.Options.AuthenticationFunc = func(c context.Context, input *oapifilter.AuthenticationInput) error {
fmt.Println(">>>> INSIDE AuthenticationFunc")
return nil
}
e.Use(oapimiddleware.OapiRequestValidatorWithOptions(swagger, validatorOptions))
If I don't pass a validator function, I get the Security requirements failed error
@zaccari
In my case, I can't use global security, there are some my end-points that didn't requires authorization(jwt token), something like user registration etc, because of that, I solve my problem by creating custom oapi validation middleware based on current oapi validation middleware but I remove security validation part, and keeping the input validation part.
And then I create another custom middleware, based on echo jwtAuth middleware for token validation + user info extraction. and finally put that middleware to intercept request to oapi path that require authorization, so I do security validation and user info extraction from that jwt token in one step.
@bandirsen
You can exclude your custom routes with the Skipper like this:
validatorOptions := &oapiMiddleware.Options{
Skipper: func(c echo.Context) bool {
return !strings.HasPrefix(c.Request().URL.Path, "/api/")
},
}
e.Use(oapiMiddleware.OapiRequestValidatorWithOptions(swagger, validatorOptions))
This will skip validation for routes that don't start with /api/.