CopyPastor

Detecting plagiarism made easy.

Score: 2; Reported for: String similarity, Exact paragraph match Open both answers

Possible Plagiarism

Reposted on 2019-01-21
by HungryTuna

Original Post

Original - Posted on 2019-01-21
by HungryTuna



            
Present in both answers; Present only in the new answer; Present only in the old answer;

We found that this actually is possible (as I also answered [here][1]).
Assuming that you have already setup API Gateway as an origin for your CloudFront distribution, you need to setup a [Lambda@Edge function][2] that intercepts origin requests and then signs it using [SigV4][3] so that you can restrict your API Gateway to access only via CloudFront.
There is a fair amount of conversion between normal HTTP requests and the [CloudFront event format][4] but it is all manageable.
First, create a Lambda@Edge function ([guide][5]) and then ensure its execution role has access to the API Gateway that you would like to access. For simplicity, you can use the `AmazonAPIGatewayInvokeFullAccess` managed IAM policy in your Lambda's execution role which gives it access to invoke any API Gateway within your account.
Then, if you go with using [aws4][6] as your signing client, this is what your lambda code would look like:
const aws4 = require("aws4");
const signCloudFrontOriginRequest = (request) => { const searchString = request.querystring === "" ? "" : `?${request.querystring}`; // Utilize a dummy request because the structure of the CloudFront origin request // is different than the signing client expects const dummyRequest = { host: request.origin.custom.domainName, method: request.method, path: `${request.origin.custom.path}${request.uri}${searchString}`, }; if (Object.hasOwnProperty.call(request, 'body')) { const { data, encoding } = request.body; const buffer = Buffer.from(data, encoding); const decodedBody = buffer.toString('utf8'); if (decodedBody !== '') { dummyRequest.body = decodedBody; dummyRequest.headers = { 'content-type': request.headers['content-type'][0].value }; } } // Use the Lambda's execution role credentials const credentials = { accessKeyId: process.env.AWS_ACCESS_KEY_ID, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, sessionToken: process.env.AWS_SESSION_TOKEN }; aws4.sign(dummyRequest, credentials); // Signs the dummyRequest object // Sign a clone of the CloudFront origin request with appropriate headers from the signed dummyRequest const signedRequest = JSON.parse(JSON.stringify(request)); signedRequest.headers.authorization = [ { key: "Authorization", value: dummyRequest.headers.Authorization } ]; signedRequest.headers["x-amz-date"] = [ { key: "X-Amz-Date", value: dummyRequest.headers["X-Amz-Date"] } ]; signedRequest.headers["x-amz-security-token"] = [ { key: "X-Amz-Security-Token", value: dummyRequest.headers["X-Amz-Security-Token"] } ]; return signedRequest; };
const handler = (event, context, callback) => { const request = event.Records[0].cf.request; const signedRequest = signCloudFrontOriginRequest(request); callback(null, signedRequest); }; module.exports.handler = handler;

[1]: https://stackoverflow.com/questions/48815143/does-api-gateway-behind-cloudfront-not-support-aws-iam-authentication [2]: https://docs.aws.amazon.com/lambda/latest/dg/lambda-edge.html [3]: https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html [4]: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-event-structure.html [5]: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-at-the-edge.html [6]: https://www.npmjs.com/package/aws4
We found that this actually is possible (as I also answered [here][1]).
Assuming that you have already setup API Gateway as an origin for your CloudFront distribution, you need to setup a [Lambda@Edge function][2] that intercepts origin requests and then signs it using [SigV4][3] so that you can restrict your API Gateway to access only via CloudFront.
There is a fair amount of conversion between normal HTTP requests and the [CloudFront event format][4] but it is all manageable.
First, create a Lambda@Edge function ([guide][5]) and then ensure its execution role has access to the API Gateway that you would like to access. For simplicity, you can use the `AmazonAPIGatewayInvokeFullAccess` managed IAM policy in your Lambda's execution role which gives it access to invoke any API Gateway within your account.
Then, if you go with using [aws4][6] as your signing client, this is what your lambda code would look like:
const aws4 = require("aws4");
const signCloudFrontOriginRequest = (request) => { const searchString = request.querystring === "" ? "" : `?${request.querystring}`; // Utilize a dummy request because the structure of the CloudFront origin request // is different than the signing client expects const dummyRequest = { host: request.origin.custom.domainName, method: request.method, path: `${request.origin.custom.path}${request.uri}${searchString}`, }; if (Object.hasOwnProperty.call(request, 'body')) { const { data, encoding } = request.body; const buffer = Buffer.from(data, encoding); const decodedBody = buffer.toString('utf8'); if (decodedBody !== '') { dummyRequest.body = decodedBody; dummyRequest.headers = { 'content-type': request.headers['content-type'][0].value }; } } // Use the Lambda's execution role credentials const credentials = { accessKeyId: process.env.AWS_ACCESS_KEY_ID, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, sessionToken: process.env.AWS_SESSION_TOKEN }; aws4.sign(dummyRequest, credentials); // Signs the dummyRequest object // Sign a clone of the CloudFront origin request with appropriate headers from the signed dummyRequest const signedRequest = JSON.parse(JSON.stringify(request)); signedRequest.headers.authorization = [ { key: "Authorization", value: dummyRequest.headers.Authorization } ]; signedRequest.headers["x-amz-date"] = [ { key: "X-Amz-Date", value: dummyRequest.headers["X-Amz-Date"] } ]; signedRequest.headers["x-amz-security-token"] = [ { key: "X-Amz-Security-Token", value: dummyRequest.headers["X-Amz-Security-Token"] } ]; return signedRequest; };
const handler = (event, context, callback) => { const request = event.Records[0].cf.request; const signedRequest = signCloudFrontOriginRequest(request); callback(null, signedRequest); }; module.exports.handler = handler;

[1]: https://stackoverflow.com/questions/48815143/does-api-gateway-behind-cloudfront-not-support-aws-iam-authentication [2]: https://docs.aws.amazon.com/lambda/latest/dg/lambda-edge.html [3]: https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html [4]: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-event-structure.html [5]: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-at-the-edge.html [6]: https://www.npmjs.com/package/aws4

        
Present in both answers; Present only in the new answer; Present only in the old answer;