-
-
Notifications
You must be signed in to change notification settings - Fork 6.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BUG] PHPSlim4 - Want only 1 authentication method out of multiple #4513
Comments
@Sroose Thanks for feedback. I'll add another layer of middleware that checks if request has been authorized by any auth schema. |
@wing328 or @jimschubert help me figure out specification. Spec says about Security Requirement Object:
Can you provide two spec examples when ALL security schemes MUST be satisfied and when ANY security schema from a list MUST be satisfied. It's kinda important, I can add massive security hole because of misunderstanding here. |
I'll take a look and reply over the weekend. |
Should be confirmed, but my understanding of the spec is: openapi: 3.0.1
paths:
/security-requirement-all:
post:
security:
- api_key: []
oauth: ["scope"]
/security-requirement-one-of:
post:
security:
- api_key: []
- oauth: ["scope"]
components:
securitySchemes:
api_key:
type: apiKey
name: X-Api-Key
in: header
oauth:
type: oauth2
flow:
implicit:
authorizationUrl: https://example.com/api/oauth/dialog
scopes:
scope: sample scope The first specifies a Security Requirement object with two requirements. The second gives two options for the Security Requirement object, one of which must be satisfied. |
Thanks @richardwhiuk . I've checked provided spec briefly and it passes validation. The only misspell is |
@jimschubert and @wing328 please confirm, that we understand provided spec 100% correctly. Confirm that ALL security schemas MUST be satisfied in |
I just understood that it can be even more complex: paths:
/security-requirement-all:
post:
security:
## (apiKey AND oauth) OR basic
- api_key: []
oauth: ["scope"]
- http_basic: []
responses:
200:
description: Success
/security-requirement-one-of:
post:
security:
## apiKey OR oauth OR (apiKey AND basic)
- api_key: []
- oauth: ["scope"]
- api_key: []
http_basic: []
responses:
200:
description: Success
components:
securitySchemes:
http_basic:
type: http
scheme: basic
api_key:
type: apiKey
name: X-Api-Key
in: header
oauth:
type: oauth2
flows:
implicit:
authorizationUrl: https://example.com/api/oauth/dialog
scopes:
scope: sample scope |
I think the example provided by @richardwhiuk is correct to explain AND, OR in security definitions for endpoints. Your example (even more complex) is also correct. |
@wing328 I've spend an hour yesterday and realized that both endpoints contains flat array in codegen variables. Codegen variables below: {
"operations": {
"classname": "AbstractDefaultApi",
"operation": [
{
"responseHeaders": [],
"hasAuthMethods": true,
"hasConsumes": false,
"hasProduces": false,
"hasParams": false,
"hasOptionalParams": false,
"hasRequiredParams": false,
"returnTypeIsPrimitive": false,
"returnSimpleType": false,
"subresourceOperation": false,
"isMapContainer": false,
"isListContainer": false,
"isMultipart": false,
"hasMore": true,
"isResponseBinary": false,
"isResponseFile": false,
"hasReference": false,
"isRestfulIndex": false,
"isRestfulShow": false,
"isRestfulCreate": false,
"isRestfulUpdate": false,
"isRestfulDestroy": false,
"isRestful": false,
"isDeprecated": false,
"isCallbackRequest": false,
"path": "/security-requirement-all",
"operationId": "securityRequirementAllPost",
"httpMethod": "POST",
"baseName": "Default",
"servers": [],
"allParams": [],
"bodyParams": [],
"pathParams": [],
"queryParams": [],
"headerParams": [],
"formParams": [],
"cookieParams": [],
"requiredParams": [],
"optionalParams": [],
"authMethods": [
{
"name": "api_key",
"type": "apiKey",
"hasMore": true,
"isBasic": false,
"isOAuth": false,
"isApiKey": true,
"isBasicBasic": false,
"isBasicBearer": false,
"isHttpSignature": false,
"vendorExtensions": {},
"keyParamName": "X-Api-Key",
"isKeyInQuery": false,
"isKeyInHeader": true,
"isKeyInCookie": false,
"isCode": false,
"isPassword": false,
"isApplication": false,
"isImplicit": false
},
{
"name": "http_basic",
"type": "http",
"scheme": "basic",
"hasMore": true,
"isBasic": true,
"isOAuth": false,
"isApiKey": false,
"isBasicBasic": true,
"isBasicBearer": false,
"isHttpSignature": false,
"vendorExtensions": {},
"isKeyInQuery": false,
"isKeyInHeader": false,
"isKeyInCookie": false,
"isCode": false,
"isPassword": false,
"isApplication": false,
"isImplicit": false
},
{
"name": "oauth",
"type": "oauth2",
"hasMore": false,
"isBasic": false,
"isOAuth": true,
"isApiKey": false,
"isBasicBasic": false,
"isBasicBearer": false,
"isHttpSignature": false,
"vendorExtensions": {},
"isKeyInQuery": false,
"isKeyInHeader": false,
"isKeyInCookie": false,
"flow": "implicit",
"authorizationUrl": "https://example.com/api/oauth/dialog",
"scopes": [
{
"scope": "scope",
"description": "sample scope"
}
],
"isCode": false,
"isPassword": false,
"isApplication": false,
"isImplicit": true
}
],
"tags": [
{
"name": "default"
}
],
"callbacks": [],
"imports": [],
"vendorExtensions": {},
"nickname": "securityRequirementAllPost",
"operationIdLowerCase": "securityrequirementallpost",
"operationIdCamelCase": "SecurityRequirementAllPost",
"operationIdSnakeCase": "security_requirement_all_post",
"restfulShow": false,
"restfulIndex": false,
"restfulCreate": false,
"restfulUpdate": false,
"restfulDestroy": false,
"restful": false,
"hasFormParams": false,
"hasExamples": false,
"hasBodyParam": false,
"hasPathParams": false,
"hasQueryParams": false,
"hasHeaderParams": false,
"hasCookieParams": false,
"hasResponseHeaders": false,
"bodyAllowed": true
},
{
"responseHeaders": [],
"hasAuthMethods": true,
"hasConsumes": false,
"hasProduces": false,
"hasParams": false,
"hasOptionalParams": false,
"hasRequiredParams": false,
"returnTypeIsPrimitive": false,
"returnSimpleType": false,
"subresourceOperation": false,
"isMapContainer": false,
"isListContainer": false,
"isMultipart": false,
"hasMore": false,
"isResponseBinary": false,
"isResponseFile": false,
"hasReference": false,
"isRestfulIndex": false,
"isRestfulShow": false,
"isRestfulCreate": false,
"isRestfulUpdate": false,
"isRestfulDestroy": false,
"isRestful": false,
"isDeprecated": false,
"isCallbackRequest": false,
"path": "/security-requirement-one-of",
"operationId": "securityRequirementOneOfPost",
"httpMethod": "POST",
"baseName": "Default",
"servers": [],
"allParams": [],
"bodyParams": [],
"pathParams": [],
"queryParams": [],
"headerParams": [],
"formParams": [],
"cookieParams": [],
"requiredParams": [],
"optionalParams": [],
"authMethods": [
{
"name": "api_key",
"type": "apiKey",
"hasMore": true,
"isBasic": false,
"isOAuth": false,
"isApiKey": true,
"isBasicBasic": false,
"isBasicBearer": false,
"isHttpSignature": false,
"vendorExtensions": {},
"keyParamName": "X-Api-Key",
"isKeyInQuery": false,
"isKeyInHeader": true,
"isKeyInCookie": false,
"isCode": false,
"isPassword": false,
"isApplication": false,
"isImplicit": false
},
{
"name": "http_basic",
"type": "http",
"scheme": "basic",
"hasMore": true,
"isBasic": true,
"isOAuth": false,
"isApiKey": false,
"isBasicBasic": true,
"isBasicBearer": false,
"isHttpSignature": false,
"vendorExtensions": {},
"isKeyInQuery": false,
"isKeyInHeader": false,
"isKeyInCookie": false,
"isCode": false,
"isPassword": false,
"isApplication": false,
"isImplicit": false
},
{
"name": "oauth",
"type": "oauth2",
"hasMore": false,
"isBasic": false,
"isOAuth": true,
"isApiKey": false,
"isBasicBasic": false,
"isBasicBearer": false,
"isHttpSignature": false,
"vendorExtensions": {},
"isKeyInQuery": false,
"isKeyInHeader": false,
"isKeyInCookie": false,
"flow": "implicit",
"authorizationUrl": "https://example.com/api/oauth/dialog",
"scopes": [
{
"scope": "scope",
"description": "sample scope"
}
],
"isCode": false,
"isPassword": false,
"isApplication": false,
"isImplicit": true
}
],
"tags": [
{
"name": "default"
}
],
"callbacks": [],
"imports": [],
"vendorExtensions": {},
"nickname": "securityRequirementOneOfPost",
"operationIdLowerCase": "securityrequirementoneofpost",
"operationIdCamelCase": "SecurityRequirementOneOfPost",
"operationIdSnakeCase": "security_requirement_one_of_post",
"restfulShow": false,
"restfulIndex": false,
"restfulCreate": false,
"restfulUpdate": false,
"restfulDestroy": false,
"restful": false,
"hasFormParams": false,
"hasExamples": false,
"hasBodyParam": false,
"hasPathParams": false,
"hasQueryParams": false,
"hasHeaderParams": false,
"hasCookieParams": false,
"hasResponseHeaders": false,
"bodyAllowed": true
}
],
"pathPrefix": "default",
"userClassname": "DefaultApi"
}
} It seems to me that we need |
Bug Report Checklist
Actual: adds all security schemes in middlewares that all get executed.
Expected: only one security scheme should match.
Description
The generator does not take into account the fact that multiple security schemes are defined as 'OR'. In other words, the generated PHP Slim code will always try to perform all authentication methods simultaneously.
They are added in the middewares like this:
openapi-generator version
4.2.1
OpenAPI declaration file content or url
Steps to reproduce
Create an OpenApi operation with multiple possible security schemes.
Related issues/PRs
Looks similar to #3844 for Python. Also #797 seems relavant.
The text was updated successfully, but these errors were encountered: