📝

AWS IoT Core のカスタムオーソライザーを AWS CLI で作成してみた

に公開

Creating and managing custom authorizers (CLI) - AWS IoT Core
上記ドキュメントをベースに AWS CLI で作成してみました。

前提

  • AWS CLI の実行環境は CloudShell
  • Lambda の実行ロールは作成済み: AdministratorAccess を付与

1. Lambda 関数の作成

アカウント ID は適宜置換してください。

$ cat > authorizer_function.js << 'EOF'
exports.handler = function(event, context, callback) { 
    var uname = event.protocolData.mqtt.username;
    var pwd = event.protocolData.mqtt.password;
    var buff = Buffer.from(pwd, 'base64');
    var passwd = buff.toString('ascii');
    
    console.log('Username: ' + uname);
    console.log('Password: ' + passwd);
    
    switch (passwd) { 
        case 'test': 
            callback(null, generateAuthResponse(passwd, 'Allow')); 
            break;
        default: 
            callback(null, generateAuthResponse(passwd, 'Deny'));  
    }
};

var generateAuthResponse = function(token, effect) { 
    var authResponse = {}; 
    authResponse.isAuthenticated = true; 
    authResponse.principalId = 'TEST123'; 
    
    var policyDocument = {}; 
    policyDocument.Version = '2012-10-17'; 
    policyDocument.Statement = []; 
    
    var connectStatement = {};
    connectStatement.Action = ["iot:Connect"];
    connectStatement.Effect = effect;
    connectStatement.Resource = ["arn:aws:iot:ap-northeast-1:012345678901:client/test-client"];
    
    var publishStatement = {}; 
    publishStatement.Action = ["iot:Publish"]; 
    publishStatement.Effect = effect; 
    publishStatement.Resource = ["arn:aws:iot:ap-northeast-1:012345678901:topic/test/topic"]; 
    
    policyDocument.Statement[0] = connectStatement;
    policyDocument.Statement[1] = publishStatement; 
    authResponse.policyDocuments = [policyDocument]; 
    authResponse.disconnectAfterInSeconds = 3600; 
    authResponse.refreshAfterInSeconds = 300;
    
    return authResponse; 
};
EOF

$ zip authorizer_function.zip authorizer_function.js

$ aws lambda create-function \
--function-name IoTCustomAuthorizer \
--runtime nodejs22.x \
--role arn:aws:iam::012345678901:role/LambdaBasicExecutionRole \
--handler authorizer_function.handler \
--zip-file fileb://authorizer_function.zip

2. カスタムオーソライザーの作成

$ aws iot create-authorizer \
--authorizer-name IoTCustomAuthorizer \
--authorizer-function-arn arn:aws:lambda:ap-northeast-1:012345678901:function:IoTCustomAuthorizer \
--status ACTIVE \
--signing-disabled

3. Lambda のリソースベースポリシーを作成

$ aws lambda add-permission \
--function-name IoTCustomAuthorizer \
--principal iot.amazonaws.com \
--source-arn arn:aws:iot:ap-northeast-1:012345678901:authorizer/IoTCustomAuthorizer \
--statement-id IoTCustomAuthorizerInvoke \
--action lambda:InvokeFunction

4. カスタムオーソライザーのテスト

$ echo -n test | base64
dGVzdA==

$ aws iot test-invoke-authorizer \
--authorizer-name IoTCustomAuthorizer \
--mqtt-context '{"username": "testuser", "password": "dGVzdA==", "clientId":"test-client"}'

# 以下のようなレスポンスを取得できれば成功
{
    "isAuthenticated": true,
    "principalId": "TEST123",
    "policyDocuments": [
        {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Action": [
                        "iot:Connect"
                    ],
                    "Effect": "Allow",
                    "Resource": [
                        "arn:aws:iot:ap-northeast-1:012345678901:client/test-client"
                    ]
                },
                {
                    "Action": [
                        "iot:Publish"
                    ],
                    "Effect": "Allow",
                    "Resource": [
                        "arn:aws:iot:ap-northeast-1:012345678901:topic/test/topic"
                    ]
                }
            ]
        }
    ],
    "refreshAfterInSeconds": 300,
    "disconnectAfterInSeconds": 3600
}

# 認証失敗のテスト
$ echo -n wrong | base64
d3Jvbmc=

$ aws iot test-invoke-authorizer \
--authorizer-name IoTCustomAuthorizer \
--mqtt-context '{"username": "testuser", "password": "d3Jvbmc=", "clientId":"test-client"}'

{
    "isAuthenticated": true,
    "principalId": "TEST123",
    "policyDocuments": [
        {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Action": [
                        "iot:Connect"
                    ],
                    "Effect": "Deny",
                    "Resource": [
                        "arn:aws:iot:ap-northeast-1:012345678901:client/test-client"
                    ]
                },
                {
                    "Action": [
                        "iot:Publish"
                    ],
                    "Effect": "Deny",
                    "Resource": [
                        "arn:aws:iot:ap-northeast-1:012345678901:topic/test/topic"
                    ]
                }
            ]
        }
    ],
    "refreshAfterInSeconds": 300,
    "disconnectAfterInSeconds": 3600
}

成功、失敗のいずれも動作確認できました。

まとめ

今回は AWS IoT Core のカスタムオーソライザーを AWS CLI で作成してみました。
どなたかの参考になれば幸いです。

参考資料

Discussion