定义您的 Lambda 函数 - Amazon IoT Core
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

定义您的 Lambda 函数

Amazon IoT Core 调用您的授权方时,它会触发与授权方关联的 Lambda 以及包含以下 JSON 对象的事件。示例 JSON 对象包含所有可能的字段。不包括与连接请求无关的任何字段。

{     "token" :"aToken",     "signatureVerified": Boolean, // Indicates whether the device gateway has validated the signature.     "protocols": ["tls", "http", "mqtt"], // Indicates which protocols to expect for the request.     "protocolData": {         "tls" : {             "serverName": "serverName" // The server name indication (SNI) host_name string.         },         "http": {             "headers": {                 "#{name}": "#{value}"             },             "queryString": "?#{name}=#{value}"         },         "mqtt": {             "username": "myUserName",             "password": "myPassword", // A base64-encoded string.             "clientId": "myClientId" // Included in the event only when the device sends the value.         }     },     "connectionMetadata": {         "id": UUID // The connection ID. You can use this for logging.     }, }

Lambda 函数应使用此信息对传入连接进行身份验证,并决定允许在连接中执行哪些操作。函数应发送包含以下值的响应。

  • isAuthenticated:一个布尔值,指示是否已对请求进行身份验证。

  • principalId:字母数字字符串,它充当自定义授权请求发送的令牌的标识符。该值必须是包含至少一个字符且不超过 128 个字符的字母数字字符串,并与此正则表达式(正则表达式)模式匹配:([a-zA-Z0-9]){1,128}。在 Amazon IoT Core 中不允许将非字母数字的特殊字符用于 principalId。如果 principalId 允许使用非字母数字的特殊字符,请参阅其它 Amazon 服务的文档。

  • policyDocuments:JSON 格式的 Amazon IoT Core 策略文档的列表。有关创建 Amazon IoT Core 策略的更多信息,请参阅 Amazon IoT Core 策略。策略文档的数量最多为 10 个。每个策略文档最多可以包含 2048 个字符。

  • disconnectAfterInSeconds:指定与 Amazon IoT Core 网关的连接的最大持续时间(以秒为单位)的整数。最小值为 300 秒,最大值为 86400 秒。默认值是 86,400。

    注意

    disconnectAfterInSeconds 的值(由 Lambda 函数返回)在建立连接时设置。在后续策略刷新 Lambda 调用过程中,将无法修改此值。

  • refreshAfterInSeconds:指定策略刷新之间间隔的整数。当此时间间隔过去时,Amazon IoT Core 将调用 Lambda 函数以允许策略刷新。最小值为 300 秒,最大值为 86400 秒。

 以下 JSON 对象包含 Lambda 函数可以发送的响应示例。

{ "isAuthenticated":true, //A Boolean that determines whether client can connect. "principalId": "xxxxxxxx",  //A string that identifies the connection in logs. "disconnectAfterInSeconds": 86400,  "refreshAfterInSeconds": 300,   "policyDocuments": [       {         "Version": "2012-10-17",         "Statement": [            {               "Action": "iot:Publish",               "Effect": "Allow",               "Resource": "arn:aws:iot:us-east-1:<your_aws_account_id>:topic/customauthtesting"             }          ]        }     ] }

policyDocument 值必须包含一个有效的 Amazon IoT Core 策略文档。有关 Amazon IoT Core 策略的更多信息,请参阅 Amazon IoT Core 策略。在通过 TLS 的 MQTT 和通过 WebSockets 的 MQTT 连接中,Amazon IoT Core 将根据 refreshAfterInSeconds 字段中指定的间隔缓存此策略。在 HTTP 连接的情况下,每个授权请求都会调用 Lambda 函数,除非您的设备使用 HTTP 持久连接(也称为 HTTP 保持活动状态或 HTTP 连接重用),否则您可以在配置授权方时选择启用缓存。在此间隔期间,Amazon IoT Core 针对此缓存策略授权已建立的连接中的操作,而不会再次触发 Lambda 函数。如果自定义身份验证过程中出现故障,则 Amazon IoT Core 将终止连接。如果连接打开的时间超过 disconnectAfterInSeconds 参数中指定的值,则 Amazon IoT Core 也会终止连接。

下面的 JavaScript 包含一个示例 Node.js Lambda 函数,该函数在值为 test 的 MQTT Connect 消息中查找密码,并使用名为 myClientName 的客户端返回授予权限以连接到 Amazon IoT Core 的策略,同时发布到包含相同客户端名称的主题。如果未找到预期密码,则返回拒绝这两个操作的策略。

// A simple Lambda function for an authorizer. It demonstrates // how to parse an MQTT password and generate a response. exports.handler = function(event, context, callback) {     var uname = event.protocolData.mqtt.username;     var pwd = event.protocolData.mqtt.password;     var buff = new Buffer(pwd, 'base64');     var passwd = buff.toString('ascii');     switch (passwd) {         case 'test':             callback(null, generateAuthResponse(passwd, 'Allow')); break;         default:             callback(null, generateAuthResponse(passwd, 'Deny'));       } }; // Helper function to generate the authorization response. var generateAuthResponse = function(token, effect) { var authResponse = {}; authResponse.isAuthenticated = true; authResponse.principalId = 'TEST123'; var policyDocument = {}; policyDocument.Version = '2012-10-17 '; policyDocument.Statement = []; var publishStatement = {}; var connectStatement = {}; connectStatement.Action = ["iot:Connect"]; connectStatement.Effect = effect; connectStatement.Resource = ["arn:aws:iot:us-east-1:123456789012:client/myClientName"]; publishStatement.Action = ["iot:Publish"]; publishStatement.Effect = effect; publishStatement.Resource = ["arn:aws:iot:us-east-1:123456789012:topic/telemetry/myClientName"]; policyDocument.Statement[0] = connectStatement; policyDocument.Statement[1] = publishStatement; authResponse.policyDocuments = [policyDocument]; authResponse.disconnectAfterInSeconds = 3600; authResponse.refreshAfterInSeconds = 300; return authResponse; }

上述 Lambda 函数在收到 MQTT Connect 消息中的预期密码 test 时返回以下 JSON。passwordprincipalId 属性的值将是来自 MQTT Connect 消息的值。

{ "password": "password", "isAuthenticated": true, "principalId": "principalId", "policyDocuments": [ { "Version": "2012-10-17", "Statement": [ { "Action": "iot:Connect", "Effect": "Allow", "Resource": "*" }, { "Action": "iot:Publish", "Effect": "Allow", "Resource": "arn:aws:iot:region:accountId:topic/telemetry/${iot:ClientId}" }, { "Action": "iot:Subscribe", "Effect": "Allow", "Resource": "arn:aws:iot:region:accountId:topicfilter/telemetry/${iot:ClientId}" }, { "Action": "iot:Receive", "Effect": "Allow", "Resource": "arn:aws:iot:region:accountId:topic/telemetry/${iot:ClientId}" } ] } ], "disconnectAfterInSeconds": 3600, "refreshAfterInSeconds": 300 }