

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 预先预调配挂钩
<a name="pre-provisioning-hook"></a>

AWS 建议在创建配置模板时使用预配置挂钩功能，以便更好地控制您的账户已登录的设备和设备数量。预调配挂钩是 Lambda 函数，可在验证设备传递的参数后允许预调配设备。在您预调配设备之前，此 Lambda 函数必须存在于您的账户中，因为每次设备通过 [RegisterThing](fleet-provision-api.md#register-thing) 发送请求时都会调用该函数。

**重要**  
请务必在附加到 Lambda 操作策略的全局条件上下文键中包含 `source-arn` 或 `source-account`，以便防范权限操纵。有关此问题的更多信息，请参阅[防止跨服务混淆座席](cross-service-confused-deputy-prevention.md)。

对于要预调配的设备，Lambda 函数必须接受输入对象并返回本节所述的输出对象。仅当 Lambda 函数返回带有 `"allowProvisioning": True` 的对象时，预调配才会继续。

## 预先预调配挂钩输入
<a name="pre-provisioning-hook-input"></a>

AWS IoT 当设备向注册时，会将此对象发送到 Lambda 函数。 AWS IoT

```
{
    "claimCertificateId" : "string",
    "certificateId" : "string",
    "certificatePem" : "string",
    "templateArn" : "arn:aws:iot:us-east-1:1234567890:provisioningtemplate/MyTemplate",
    "clientId" : "221a6d10-9c7f-42f1-9153-e52e6fc869c1",
    "parameters" : {
        "string" : "string",
        ...
    }
}
```

传递给 Lambda 函数的 `parameters` 对象包含 `parameters` 参数中的属性，该参数在 [RegisterThing](fleet-provision-api.md#register-thing) 请求有效载荷中传入。

## 预先预调配挂钩返回值
<a name="pre-provisioning-hook-output"></a>

Lambda 函数必须返回一个响应，指示它是否已授权预调配请求以及要覆盖的任意属性的值。

以下是来自预先预调配函数的成功响应示例。

```
{
    "allowProvisioning": true,
    "parameterOverrides" : {
        "Key": "newCustomValue",
        ...
    }
}
```

`"parameterOverrides"` 值将添加到 [RegisterThing](fleet-provision-api.md#register-thing) 申请有效载荷的 `"parameters"` 参数中。

**注意**  
如果 Lambda 函数失败，则配置请求将失败，`ACCESS_DENIED`并在 Logs 中记录错误。 CloudWatch 
如果 Lambda 函数未在响应中返回 `"allowProvisioning": "true"`，则预调配请求将失败并显示 `ACCESS_DENIED`。
Lambda 函数必须在 5 秒内完成执行并返回，否则预调配请求将失败。

## 预先预调配挂钩 Lambda 示例
<a name="pre-provisioning-example"></a>

------
#### [ Python ]

在 Python 中预先预调配挂钩 Lambda 示例。

```
import json

def pre_provisioning_hook(event, context):
    print(event)

    return {
        'allowProvisioning': True,
        'parameterOverrides': {
            'DeviceLocation': 'Seattle'
        }
    }
```

------
#### [ Java ]

在 Java 中预先预调配挂钩 Lambda 示例。

处理程序类：

```
package example;

import java.util.Map;
import java.util.HashMap;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

public class PreProvisioningHook implements RequestHandler<PreProvisioningHookRequest, PreProvisioningHookResponse> {

    public PreProvisioningHookResponse handleRequest(PreProvisioningHookRequest object, Context context) {
        Map<String, String> parameterOverrides = new HashMap<String, String>();
        parameterOverrides.put("DeviceLocation", "Seattle");

        PreProvisioningHookResponse response = PreProvisioningHookResponse.builder()
                .allowProvisioning(true)
                .parameterOverrides(parameterOverrides)
                .build();

        return response;
    }

}
```

请求类：

```
package example;

import java.util.Map;
import lombok.Builder;
import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class PreProvisioningHookRequest {
    private String claimCertificateId;
    private String certificateId;
    private String certificatePem;
    private String templateArn;
    private String clientId;
    private Map<String, String> parameters;
}
```

响应类：

```
package example;

import java.util.Map;
import lombok.Builder;
import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;


@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class PreProvisioningHookResponse {
    private boolean allowProvisioning;
    private Map<String, String> parameterOverrides;
}
```

------
#### [ JavaScript ]

中预置挂钩 Lambda JavaScript 的示例。

```
exports.handler = function(event, context, callback) {
    console.log(JSON.stringify(event, null, 2));
    var reply = { 
        allowProvisioning: true,
        parameterOverrides: {
            DeviceLocation: 'Seattle'
        }
     };
     callback(null, reply);
}
```

------