

# 关联 CloudFront 连接函数
<a name="connection-functions"></a>

利用 CloudFront 连接函数，您可以在 TLS 握手过程中实施自定义证书验证逻辑，从而扩展内置 mTLS 身份验证功能。

## 什么是连接函数？
<a name="what-are-connection-functions"></a>

连接函数是指在客户端证书验证完成后，在 TLS 握手过程中运行的 JavaScript 函数。经过验证的客户端证书将传递给连接函数，此时连接函数可进一步决定是否授予访问权限。有关连接函数的详细信息，请参阅[使用 CloudFront Functions 在边缘进行自定义](cloudfront-functions.md)。

## 连接函数与 mTLS 的协作方式
<a name="how-connection-functions-work"></a>

当客户端尝试与 CloudFront 分配建立 mTLS 连接时，将遵循以下流程：

1. 客户端向 CloudFront 边缘站点发起 TLS 握手请求。

1. CloudFront 请求并接收客户端证书。

1. CloudFront 对信任存储执行标准证书验证。

1. 如果证书通过标准验证，CloudFront 将调用您的连接函数。如果在 **ViewerMtlsConfig** 中启用了 **IgnoreCertificateExpiry**，则虽已到期但其他条件均有效的证书也将传递至连接函数。如果客户端证书无效，则不会调用连接函数。

1. 您的连接函数接收经过解析的证书信息和连接详细信息。

1. 函数根据自定义逻辑做出允许/拒绝决定。

1. CloudFront 根据您的决定完成或终止 TLS 连接。

在验证模式和可选模式（当客户端提供证书时）下，都将调用连接函数。

## 创建连接函数
<a name="create-connection-function"></a>

您可以使用 CloudFront 控制台或 AWS CLI 创建连接函数。

### 创建连接函数（控制台）
<a name="create-connection-function-console"></a>

1. 登录 AWS 管理控制台，并通过以下网址打开 CloudFront 控制台：[https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)。

1. 在导航窗格中，选择 **Functions**（函数）。

1. 选择**连接函数**选项卡，然后选择**创建连接函数**。

1. 输入在 AWS 账户中唯一的函数名称。

1. 选择**继续**。

1. 在函数编辑器中，编写用于证书验证的 JavaScript 代码。函数处理程序必须调用 allow 或 deny。

1. 可选：可将 KeyValueStore 与连接函数关联以实施吊销控制。

1. 选择**保存更改**。

### 创建连接函数（AWS CLI）
<a name="create-connection-function-cli"></a>

以下示例演示如何创建连接函数：

在单独的文件（例如 code.js）中编写函数代码：

```
function connectionHandler(connection) {
  connection.allow();
}
```

```
aws cloudfront create-connection-function \
  --name "certificate-validator" \
  --connection-function-config '{
      "Comment": "Client certificate validation function",
      "Runtime": "cloudfront-js-2.0"
  }' \
  --connection-function-code fileb://code.js
```

## 连接函数代码结构
<a name="connection-function-code-structure"></a>

连接函数会实施 connectionHandler 函数，该函数接收一个包含证书和连接信息的连接对象。您的函数必须使用 `connection.allow()` 或 `connection.deny()` 来决定是否允许该连接。

### 基本连接函数示例
<a name="basic-connection-function-example"></a>

以下示例展示了一个简单的连接函数，该函数用于验证客户端证书的主题字段：

```
function connectionHandler(connection) {
    // Only process if a certificate was presented
    if (!connection.clientCertificate) {
        console.log("No certificate presented");
        connection.deny();
    }
    
    // Check the subject field for specific organization
    const subject = connection.clientCertificate.certificates.leaf.subject;
    if (!subject.includes("O=ExampleCorp")) {
        console.log("Certificate not from authorized organization");
       connection.deny();
    } else {
        // All checks passed
        console.log("Certificate validation passed");
        connection.allow();
    }
}
```

此处提供了连接对象上可用的客户端证书属性的完整规范：

```
{
  "connectionId": "Fdb-Eb7L9gVn2cFakz7wWyBJIDAD4-oNO6g8r3vXDV132BtnIVtqDA==", // Unique identifier for this TLS connection
  "clientIp": "203.0.113.42", // IP address of the connecting client (IPv4 or IPv6)
  "clientCertificate": {
    "certificates": {
      "leaf": {
        "subject": "CN=client.example.com,O=Example Corp,C=US", // Distinguished Name (DN) of the certificate holder
        "issuer": "CN=Example Corp Intermediate CA,O=Example Corp,C=US", // Distinguished Name (DN) of the certificate authority that issued this certificate
        "serialNumber": "4a:3f:5c:92:d1:e8:7b:6c", // Unique serial number assigned by the issuing CA (hexadecimal)
        "validity": {
          "notBefore": "2024-01-15T00:00:00Z", // Certificate validity start date (ISO 8601 format)
          "notAfter": "2025-01-14T23:59:59Z"   // Certificate expiration date (ISO 8601 format)
        },
        "sha256Fingerprint": "a1b2c3d4e5f6...abc123def456", // SHA-256 hash of the certificate (64 hex characters)
      },
    },
  },
}
```

## 关联连接函数
<a name="associate-connection-function-section"></a>

创建连接函数后，必须将其发布到 LIVE 阶段并与分配相关联。

### 发布并关联连接函数（控制台）
<a name="publish-associate-console"></a>

1. 登录 AWS 管理控制台，并通过以下网址打开 CloudFront 控制台：[https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)。

1. 在导航窗格中，选择**函数**

1. 选择**连接函数**选项卡，然后选择您的连接函数。

1. 选择**发布**以将其移至 LIVE 阶段。

1. 在“发布”部分下，在关联的分配表中选择**添加关联**。

1. 选择要关联的已启用查看器 mTLS 的分配。

或者，您也可以从分配详细信息页面关联已发布的连接函数。

1. 导航到控制台主页，该页面上列出了您的所有分配。

1. 选择要关联的分配。

1. 选择**常规**选项卡。

1. 在**设置**部分中，选择**编辑**。

1. 在**连接性**部分中，找到**查看器双向身份验证(mTLS)**。

1. 对于**连接函数**，选择您的函数。

1. 选择**保存更改**。

### 关联连接函数（AWS CLI）
<a name="associate-connection-function-cli"></a>

以下示例演示如何将连接函数与分配相关联：

```
// DistributionConfig:
{
   ...other settings,
    "ConnectionFunctionAssociation": {
        "Id": "cf_30c2CV2elHwCoInb3LtcaUJkZeD"
    }
}
```

## 连接函数的使用案例
<a name="connection-function-use-cases"></a>

连接函数支持多种高级 mTLS 使用案例：
+ **证书属性验证**：验证客户端证书中的特定字段，例如组织单元要求或主题备用名称模式。
+ **证书吊销检查**：使用 KeyValueStore 存储已吊销证书的序列号，以实施自定义证书吊销检查。
+ **基于 IP 的证书策略**：根据客户端 IP 地址或地理限制应用不同的证书策略。
+ **多租户验证**：实施特定于租户的验证规则，根据主机名或证书属性应用不同的证书要求。

**注意**  
在 TLS 握手过程中，针对每个客户端连接运行一次连接函数。  
连接函数只能允许或拒绝连接，而不能修改 HTTP 请求/响应。  
仅 LIVE 阶段函数（已发布）能够与分配相关联。  
每个分配可拥有最多一个连接函数。

## 后续步骤
<a name="connection-function-next-steps"></a>

将连接函数与 CloudFront 分配关联后，您可以配置可选设置以自定义 mTLS 实施的行为。有关配置其他设置（例如，可选的客户端证书验证模式）的详细说明，请参阅[配置其他设置](configuring-additional-settings.md)。