How to whitelist Authorization header in CloudFront custom Origin Request Policy

amazon-cloudfrontamazon-web-servicesauthorizationcachehttp-headers

I have created the following CloudFront Origin Request Policy:

enter image description here

I need Authorization header (without Authorization header the AntiForgeryToken header is not forwarded) but I do not understand why CloudFront does not allow adding Authorization header to the policy?

I get the following error:

400 The parameter Headers contains Authorization that is not allowed.

I have followed this document and added Authorization header to Cache Policy, but still don't get the AntiForgeryToken in my requests…

If I use the legacy cache policy (instead of creating my own custom policy) then I am able to Whitelist Authorization header but don't know why I am not able to do it in my own custom policy?

enter image description here

Best Answer

It is possible to use the Origin Request Policy to forward all headers (use the Managed-AllViewer) which includes Authorization. As stated above, this does cause a conflict with API Gateway because the HOST header doesn't match the request (request is coming from CloudFront, HOST is from the user) and so API Gateway will return a 403. In order to deal with that, you can deploy a Lambda@Edge function to rewrite the HOST header to match CloudFront. API Gateway will then accept the request.

To do that, create a Lambda function in US-EAST-1 (must be here for replication purposes, add edgelambda.amazonaws.com to the trusted entities on the Lambda's role, and then add a CloudFront trigger to the Lambda function for origin-requests and specify the distribution you want to use it.

enter image description here

Here's a sample Lambda@Edge function in Node.JS to perform that task:

'use strict';

exports.handler = (event, context, callback) => {
  const request = event.Records[0].cf.request;

  /* Set host header to API GW domain*/
  request.headers['host'] = [{ key: 'host', value: request.origin.custom.domainName }];
  console.log('successfully executed Lambda at Edge')
  callback(null, request);
};