本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
定义您的 Lambda 函数
当Amazon IoT Core调用您的授权方时,它会使用包含以下 JSON 对象的事件触发与授权方关联的 Lambda。示例 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_namestring. }, "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}。不允许在 inprincipalId中Amazon IoT Core使用非字母数字的特殊字符。如果允许使用非字母数字特殊字符,请参阅其他Amazon服务的文档。principalId -
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连接的 MQ Amazon IoT Core TT 中,在字段值中指定的间隔内缓存此策略。refreshAfterInSeconds在 HTTP 连接的情况下,每个授权请求都会调用 Lambda 函数,除非您的设备使用 HTTP 持久连接(也称为 HTTP 保持活动状态或 HTTP 连接重用),否则您可以在配置授权方时选择启用缓存。在此间隔内,Amazon IoT Core授权在已建立的连接中针对此缓存策略执行操作,而无需再次触发您的 Lambda 函数。如果在自定义身份验证期间出现故障,则Amazon IoT Core终止连接。 Amazon IoT Core如果连接的打开时间超过disconnectAfterInSeconds参数中指定的值,也会终止该连接。
以下内容 JavaScript 包含一个 Node.js Lambda 函数示例,该函数在 MQTT Connect 消息中查找值为test的密码,并返回一个策略,该策略授予使用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。password 和 principalId 属性的值将是来自 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 }