-
Notifications
You must be signed in to change notification settings - Fork 4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(apigateway): CORS OPTIONS method should not require auth (#22402)
When you create a RestApi and you provide `defaultCorsPreflightOptions` we automatically create a CORS OPTIONS method for each method. If you also provide `defaultMethodOptions` then those default options get passed through to the CORS OPTION method as well. In the case of authentication options this should not be the case. This PR explicitly sets the authentication related options to NONE values which overrides whatever is provided in `defaultMethodOptions`. I've updated an integration tests to assert that an OPTIONS call is successful (I also tested before the fix to assert that it failed). fixes #8615 ---- ### All Submissions: * [ ] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Unconventional Dependencies: * [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies) ### New Features * [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
- Loading branch information
Showing
22 changed files
with
2,688 additions
and
733 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 0 additions & 41 deletions
41
packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer.lit.ts
This file was deleted.
Oops, something went wrong.
127 changes: 127 additions & 0 deletions
127
packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
import * as path from 'path'; | ||
import * as lambda from '@aws-cdk/aws-lambda'; | ||
import { App, Stack, Duration } from '@aws-cdk/core'; | ||
import { IntegTest, ExpectedResult, Match } from '@aws-cdk/integ-tests'; | ||
import { MockIntegration, PassthroughBehavior, RestApi, TokenAuthorizer, Cors } from '../../lib'; | ||
|
||
const app = new App(); | ||
const stack = new Stack(app, 'TokenAuthorizerInteg'); | ||
|
||
const authorizerFn = new lambda.Function(stack, 'MyAuthorizerFunction', { | ||
runtime: lambda.Runtime.NODEJS_14_X, | ||
handler: 'index.handler', | ||
code: lambda.AssetCode.fromAsset(path.join(__dirname, 'integ.token-authorizer.handler')), | ||
}); | ||
|
||
const authorizer = new TokenAuthorizer(stack, 'MyAuthorizer', { | ||
handler: authorizerFn, | ||
}); | ||
|
||
const restapi = new RestApi(stack, 'MyRestApi', { | ||
cloudWatchRole: true, | ||
defaultMethodOptions: { | ||
authorizer, | ||
}, | ||
defaultCorsPreflightOptions: { | ||
allowOrigins: Cors.ALL_ORIGINS, | ||
}, | ||
}); | ||
|
||
|
||
restapi.root.addMethod('ANY', new MockIntegration({ | ||
integrationResponses: [ | ||
{ statusCode: '200' }, | ||
], | ||
passthroughBehavior: PassthroughBehavior.NEVER, | ||
requestTemplates: { | ||
'application/json': '{ "statusCode": 200 }', | ||
}, | ||
}), { | ||
methodResponses: [ | ||
{ statusCode: '200' }, | ||
], | ||
}); | ||
|
||
const integ = new IntegTest(app, 'apigw-token-auth', { | ||
testCases: [stack], | ||
}); | ||
const hostName = `${restapi.restApiId}.execute-api.${stack.region}.${stack.urlSuffix}`; | ||
const testFunc = new lambda.Function(stack, 'InvokeFunction', { | ||
memorySize: 250, | ||
timeout: Duration.seconds(10), | ||
code: lambda.Code.fromInline(` | ||
const https = require('https'); | ||
const options = { | ||
hostname: '${hostName}', | ||
path: '/${restapi.deploymentStage.stageName}', | ||
}; | ||
exports.handler = async function(event) { | ||
console.log(event); | ||
options.method = event.method; | ||
if ('authorization' in event) { | ||
options.headers = { | ||
Authorization: event.authorization, | ||
}; | ||
} | ||
let dataString = ''; | ||
const response = await new Promise((resolve, reject) => { | ||
const req = https.request(options, (res) => { | ||
res.on('data', data => { | ||
dataString += data; | ||
}) | ||
res.on('end', () => { | ||
resolve({ | ||
statusCode: res.statusCode, | ||
body: dataString, | ||
}); | ||
}) | ||
}); | ||
req.on('error', err => { | ||
reject({ | ||
statusCode: 500, | ||
body: JSON.stringify({ | ||
cause: 'Something went wrong', | ||
error: err, | ||
}) | ||
}); | ||
}); | ||
req.end(); | ||
}); | ||
return response; | ||
} | ||
`), | ||
handler: 'index.handler', | ||
runtime: lambda.Runtime.NODEJS_16_X, | ||
}); | ||
|
||
const invokeGet = integ.assertions.invokeFunction({ | ||
functionName: testFunc.functionName, | ||
payload: JSON.stringify({ | ||
method: 'GET', | ||
authorization: 'allow', | ||
}), | ||
}); | ||
invokeGet.expect(ExpectedResult.objectLike({ | ||
Payload: Match.stringLikeRegexp('200'), | ||
})); | ||
|
||
const invokeGetDeny = integ.assertions.invokeFunction({ | ||
functionName: testFunc.functionName, | ||
payload: JSON.stringify({ | ||
method: 'GET', | ||
authorization: 'deny', | ||
}), | ||
}); | ||
invokeGetDeny.expect(ExpectedResult.objectLike({ | ||
Payload: Match.stringLikeRegexp('User is not authorized to access this resource with an explicit deny'), | ||
})); | ||
|
||
const invokeOptions = integ.assertions.invokeFunction({ | ||
functionName: testFunc.functionName, | ||
payload: JSON.stringify({ | ||
method: 'OPTIONS', | ||
}), | ||
}); | ||
invokeOptions.expect(ExpectedResult.objectLike({ | ||
Payload: Match.stringLikeRegexp('204'), | ||
})); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.