

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 限制對 AWS Lambda Web 函數原始伺服器的存取
<a name="private-content-restricting-access-to-lambda-web"></a>

您可以使用原始存取控制 (OAC) 來限制對 AWS Lambda Web 函數原始伺服器的存取。Lambda Web Function 提供自己的區域或全域 HTTPS 端點，您可以將其用作 CloudFront 分佈的原始網域。如需 Lambda Web 函數的詳細資訊，請參閱《 *AWS Lambda 開發人員指南*》中的 [AWS Lambda Web 函數](https://docs.aws.amazon.com/lambda/latest/dg/web-functions.html)。

**注意**  
包含選擇加入區域的全域端點不支援具有 Lambda Web 函數的 OAC。如果端點將請求路由到選擇加入區域，CloudFront 就無法簽署該區域的請求。原始伺服器接著會傳回 HTTP 403 （禁止） 錯誤。與全域端點相關聯的所有區域都必須是預設啟用的區域。

如需搭配 Lambda 函數 URL 原始伺服器使用 OAC 的詳細資訊，請參閱 [限制對 AWS Lambda 函數 URL 原始伺服器的存取](private-content-restricting-access-to-lambda.md)。

## 先決條件
<a name="oac-prerequisites-lambda-web"></a>

在建立和設定 OAC 之前，您必須擁有具有 Lambda Web 函數作為原始伺服器的 CloudFront 分佈。原始網域名稱是 Lambda Web 函數端點的主機名稱。CloudFront 會從主機名稱識別[端點類型](https://docs.aws.amazon.com/lambda/latest/dg/web-functions-endpoints.html#web-functions-endpoint-types)：
+ 區域端點 (`HomeRegion` 和 `PerRegion`端點類型） – 主機名稱結尾為 `.lambda-web.{{AWS-Region}}.on.aws`
+ 全域端點 (`MultiRegion` 端點類型） – 主機名稱結尾為 `.lambda-web.global.on.aws`

您的組態也必須符合下列要求：
+ **端點身分驗證類型** – 端點的身分驗證類型必須為 `IamAuth`。透過 `IamAuth`，端點會使用 AWS Identity and Access Management (IAM) 來驗證和授權請求。對於來自 CloudFront 的請求，授權是以 Lambda Web Function 的資源型政策為基礎。CloudFront 會代表檢視器簽署請求，而端點會驗證簽章。如需詳細資訊，請參閱《 *AWS Lambda 開發人員指南*》中的 [CloudFront 整合](https://docs.aws.amazon.com/lambda/latest/dg/web-functions-endpoint-access-control.html#web-functions-endpoint-access-control-cloudfront)。
+ **快取政策** – 如果您的 Lambda Web 函數使用檢視器的`Authorization`標頭，您必須將 標頭新增至[快取政策](controlling-the-cache-key.md)。此要求適用於使用原始伺服器的每個快取行為。對於 `GET`和 `HEAD`請求，除非 `Authorization`標頭位於快取政策中，否則 CloudFront 會在轉送請求之前移除 標頭。如需詳細資訊，請參閱[HTTP 請求標頭和 CloudFront 行為 (自訂和 Amazon S3 原始伺服器)](RequestAndResponseBehaviorCustomOrigin.md#request-custom-headers-behavior)。
+ **原始伺服器請求政策** – 使用排除檢視器`Host`標頭的原始伺服器請求政策。Lambda Web 函數端點預期`Host`標頭包含原始網域名稱，而不是 CloudFront 分佈的網域名稱。如果 `Host`標頭包含分佈的網域名稱，端點會傳回 HTTP 404 （找不到） 錯誤。如果您使用受管原始伺服器請求政策，請使用 `AllViewerExceptHostHeader`，而非 `AllViewer`。如需詳細資訊，請參閱[AllViewerExceptHostHeader](using-managed-origin-request-policies.md#managed-origin-request-policy-all-viewer-except-host-header)。

**注意**  
在搭配 OAC 使用 Lambda Web 函數原始伺服器的快取行為上，不支援 Lambda@Edge 原始伺服器請求和原始伺服器回應觸發。這適用於區域和全域端點，以及直接或透過原始伺服器群組存取的原始伺服器。CloudFront 拒絕包含兩者的分佈組態。

## 授予 CloudFront 存取 Lambda Web 函數的許可
<a name="oac-permission-to-access-lambda-web"></a>

將資源型政策連接至 Lambda Web 函數，以允許 CloudFront 服務主體 (`cloudfront.amazonaws.com`) 叫用端點。叫用端點的 IAM 動作是 `lambda:InvokeWebFunctionEndpoint`。政策會連接到 Lambda Web 函數，但每個陳述式都可以將 範圍`Resource`限定為特定端點 ARN。使用 `Condition`元素來允許 CloudFront 僅在請求代表包含原始伺服器的 CloudFront 分佈時存取端點。

**Example CloudFront OAC 的資源型政策**  

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "AllowCloudFrontOACAccess",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com"
            },
            "Action": "lambda:InvokeWebFunctionEndpoint",
            "Resource": "arn:aws:lambda:us-east-1:{{111122223333}}:web-function/{{my-function}}/endpoint/{{prod}}",
            "Condition": {
                "StringEquals": {
                    "aws:SourceArn": "arn:aws:cloudfront::{{111122223333}}:distribution/{{EDFDVBD6EXAMPLE}}"
                }
            }
        }
    ]
}
```

若要連接資源型政策，請使用 **put-resource-policy**命令搭配 *函數* ARN （而非端點 ARN)：

```
aws lambda-web put-resource-policy \
  --resource-arn "arn:aws:lambda:us-east-1:{{111122223333}}:web-function/{{my-function}}" \
  --policy file://policy.json \
  --region us-east-1
```

您可以使用 **get-resource-policy**和 **delete-resource-policy**命令檢閱或移除政策。

**注意**  
對於跨多個區域的端點，Lambda 會將政策變更複寫到提供端點的所有區域。新的或更新的政策可能需要一小段時間，才能在每個區域中生效。如需詳細資訊，請參閱《 *AWS Lambda 開發人員指南*》中的[複寫和最終一致性](https://docs.aws.amazon.com/lambda/latest/dg/web-functions-permissions.html#web-functions-permissions-resource-policy-replication)。

## 建立原始存取控制
<a name="create-oac-lambda-web"></a>

若要建立原始存取控制 (OAC) CloudFormation，您可以使用 AWS 管理主控台、 AWS CLI、 或 CloudFront API。

------
#### [ Console ]

**如要建立原始存取控制**

1. 登入 AWS 管理主控台 ，並在 開啟 CloudFront 主控台[https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)。

1. 於左側導覽窗格中，選擇 **Origin access** (原始存取)。

1. 選擇 **Create control setting** (建立控制設定)。

1. 在 **Create control setting** (建立控制設定) 表單上，執行下列動作：

   1. 於 **Details** (詳細資訊) 窗格中，輸入 **Name** (名稱) 和 (選用) **Description** (描述)，以用於原始存取控制。

   1. 從**原始伺服器類型**下拉式清單中選擇 **Lambda**。此原始伺服器類型用於 Lambda URLs 和 Lambda Web 函數。

   1. 如果您的原始伺服器是全域端點 （主機名稱結尾為 `.lambda-web.global.on.aws`)，請選取**使用 SigV4a 簽署通訊協定**選項。對於區域端點 （主機名稱結尾為 `.lambda-web.{{AWS-Region}}.on.aws`)，請清除此選項。

   1. 針對**簽署行為**，選擇**一律簽署，保留檢視器授權**。此選項會出現在 **Sign 請求 （建議）** 下，這是預設選取的。Lambda Web 函數原始伺服器僅支援此簽署行為。如需詳細資訊，請參閱[簽署行為](#oac-signing-behavior-lambda-web)。

1. 選擇**建立**。

**將原始存取控制新增至分佈中的 Lambda Web 函數原始伺服器**

1. 在 [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home) 中開啟 CloudFront 主控台。

1. 選擇具有您要新增 OAC 之 Lambda Web 函數原始伺服器的分佈，然後選擇**原始**伺服器索引標籤。

1. 選取您要新增 OAC 的 Lambda Web 函數原始伺服器，然後選擇**編輯**。

1. 針對**原始存取**，選擇**原始存取控制設定 (建議使用)**。

1. 在 **Origin access control** (原始存取控制) 下拉式功能表中，選擇您想要使用的 OAC。

1. 選擇**儲存變更**。

分佈開始部署至所有 CloudFront 邊緣節點。當節點收到新組態時，它會簽署其傳送至 Lambda Web 函數原始伺服器的所有請求。

------
#### [ CLI ]

使用 **create-origin-access-control** 命令。對於區域端點 （主機名稱結尾為 `.lambda-web.{{AWS-Region}}.on.aws`)，請使用`sigv4`簽署通訊協定：

```
aws cloudfront create-origin-access-control \
    --origin-access-control-config '{
        "Name": "my-lambda-web-oac",
        "Description": "OAC for Lambda Web Function origin",
        "SigningProtocol": "sigv4",
        "SigningBehavior": "always-amz-auth",
        "OriginAccessControlOriginType": "lambda"
    }'
```

對於全域端點 （主機名稱結尾為 `.lambda-web.global.on.aws`)，請使用`sigv4a`簽署通訊協定：

```
aws cloudfront create-origin-access-control \
    --origin-access-control-config '{
        "Name": "my-lambda-web-global-oac",
        "Description": "OAC for global Lambda Web Function origin",
        "SigningProtocol": "sigv4a",
        "SigningBehavior": "always-amz-auth",
        "OriginAccessControlOriginType": "lambda"
    }'
```

------
#### [ CloudFormation ]

在 中指定下列值`OriginAccessControlConfig`：
+ `SigningProtocol`： `sigv4` （區域端點） 或 `sigv4a`（全域端點）
+ `SigningBehavior`: `always-amz-auth`
+ `OriginAccessControlOriginType`: `lambda`

**Example CloudFormation 範本**  

```
Type: AWS::CloudFront::OriginAccessControl
Properties:
  OriginAccessControlConfig:
    Description: An optional description for the origin access control
    Name: my-lambda-web-oac
    OriginAccessControlOriginType: lambda
    SigningBehavior: always-amz-auth
    SigningProtocol: sigv4a
```

如需詳細資訊，請參閱《*AWS CloudFormation 使用者指南*》中的 [AWS::CloudFront::OriginAccessControl](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-originaccesscontrol.html)。

------

只有在分佈完成部署後，OAC 才會對每個請求生效。對於跨越多個區域的端點，您先前連接的資源型政策也必須完成複寫到為端點提供服務的每個區域。在兩者都完成之前，某些請求可以接收來自原始伺服器的暫時性 HTTP 403 回應。這些錯誤會在分佈完成部署且政策完成複寫後自動解決。

## 簽署行為
<a name="oac-signing-behavior-lambda-web"></a>

Lambda Web 函數原始伺服器僅支援`always-amz-auth`簽署行為 **（一律在主控台中簽署、保留檢視器授權**)。CloudFront 一律會簽署傳送至 Lambda Web 函數的所有請求，但不會取代檢視器請求中的`Authorization`標頭。反之，CloudFront 會在專用 CloudFront 標頭中新增其簽章，並將檢視器的`Authorization`標頭傳遞至未修改的原始伺服器。透過此行為，您的 Lambda Web 函數可以接收檢視器的原始`Authorization`標頭 （例如，執行自己的身分驗證或授權）。CloudFront 仍會簽署傳送至原始伺服器的每個請求。若要轉送檢視器的`Authorization`標頭，您必須將其新增至使用原始伺服器的每個快取行為的快取[政策](controlling-the-cache-key.md)。

Lambda Web `always`函數原始伺服器不支援其他簽署行為 (`never`、 和 `no-override`)。任何其他原始伺服器類型都不支援`always-amz-auth`簽署行為，包括 Lambda 函數 URL 原始伺服器。

對於 `PUT`、 `POST`和 `PATCH`請求，CloudFront 會使用未簽署的承載 () 簽署原始伺服器請求`UNSIGNED-PAYLOAD`。CloudFront 簽章未涵蓋請求內文。簽章仍然涵蓋請求方法、路徑、查詢字串，以及識別分佈的標頭。因此，端點可以在叫用 Lambda Web 函數之前，驗證每個請求是否來自 CloudFront 代表您的分佈。請求內文受到 CloudFront 與端點之間 HTTPS 連線的傳輸中保護。您不需要在對 CloudFront 的請求中包含 `x-amz-content-sha256`標頭。如果瀏覽者傳送一個，CloudFront 不會在簽署原始伺服器請求時使用它。