amazon-web-services - 具有多个条件的 AWS IAM 策略语法错误

标签 amazon-web-services amazon-iam

我的政策不符合 AWS。 JSONlint 说我有一个有效的 json。有语法问题,但我没有看到。

此策略包含以下错误:策略不符合身份和访问管理 (IAM) 策略语法。有关 IAM 策略语法的更多信息,请参阅 AWS IAM 策略。

{
"Version": "2012-10-17",
"Statement": [
    {
        "Effect": "Allow",
        "Action": "ec2:*",
        "Resource": "*",
        "Condition": {
             "StringEquals": {"ec2:ResourceTag/sf_env": "dev",
             "StringEquals": {"ec2:Region": "us-west-2"
            }
          }
       }
    },
    {
        "Effect": "Allow",
        "Action": "rds:*",
        "Resource": "*",
        "Condition": {
          "StringEquals": { "ec2:ResourceTag/sf_env": "dev",
          "StringEquals": { "ec2:Region": "us-west-2"
            }
          }
       }
    },
    {
        "Sid": "AllowHealthCheckOnly",
        "Effect": "Allow",
        "Action": "elasticloadbalancing:Describe*",
        "Resource": "*",
        "Condition": {
            "StringEquals":{ "ec2:ResourceTag/sf_env": "dev",
            "StringEquals":{ "ec2:Region": "us-west-2"
          }
       }
    }
    },
    {
        "Sid": "ConfigureHealthCheckOnly",
        "Effect": "Allow",
        "Action": "elasticloadbalancing:ConfigureHealthCheck",
        "Resource": "arn:aws:elasticloadbalancing:us-west-2:xxxxxxxxxxxx:loadbalancer/instance1",
        "Condition": {
            "StringEquals": { "ec2:ResourceTag/sf_env": "dev",
            "StringEquals": { "ec2:Region": "us-west-2"
            }
          }
       }
    },
    {
        "Sid": "FullElasticCacheManagedPolicyPermissions",
        "Effect": "Allow",
        "Action": [
            "elasticache:*",
            "ec2:DescribeAvailibilityZones",
            "ec2:DescribeVpcs",
            "ec2:DescribeAccountAttributes",
            "ec2:DescribeSeucrityGroups",
            "cloudwatch:GetMetricStatistics",
            "cloudwatch:DescribeAlarms",
            "sns:ListTopics",
            "sns:ListSubscriptions"
        ],
        "Resource": "*",
        "Condition": {
            "StringEquals": { "ec2:ResourceTag/sf_env": "dev",
            "StringEquals": { "ec2:Region": "us-west-2"
            }
          }
       }
    }
]

}

最佳答案

JSONLint说你有语法上有效的 JSON,你确实......但问题是你成功编码的数据......没有语义意义。

看看你的最后一个条件,你写道:

    "Condition": {
        "StringEquals": { "ec2:ResourceTag/sf_env": "dev",
        "StringEquals": { "ec2:Region": "us-west-2"
        }
      }
   }

请注意:由于以下是从较大的 JSON 对象中提取的键/值片段,您必须将它们中的每一个嵌套在额外的外对 { 中。牙套} JSONLint 来解析它,实际上它是一个有效的 JSON 表示,在没有周围结构的情况下单独评估时。在测试创建示例时,我在每种情况下将这些添加到 JSONLint 输入中,并从输出中删除它们,希望是为了清晰起见。

JSONLint 重新格式化上述内容,以向您展示您正在传达的内容:
"Condition": {
            "StringEquals": {
                "ec2:ResourceTag/sf_env": "dev",
                "StringEquals": {
                    "ec2:Region": "us-west-2"
                }
            }
        }

JSON 的优势在于其简单的结构和约束:它具有 {对象 } (键/值对,其中键是字符串,值正是这句话中任何地方提到的任何类型的事物之一)... [数组 ] (值列表)... "字符串 " ... 数字(不加引号) ... bool 值( truefalse ,不加引号) ... 和 null( null ,不加引号)。
StringEquals ,正如你所表达的,上面是一个有两个键的对象,ec2:ResourceTag/sf_env (它有一个字符串作为它的值)...和 ​​StringEquals (第二次出现,它具有另一个嵌套对象作为其值)。

显然,这不是您想要的,但它是对您提供的内容的正确解释。

请注意,缩进完全是可选的,但 JSONLint 的输出格式以有意义的方式使用缩进。注意到如何 "ec2:ResourceTag/sf_env""ec2:Region"是(使用非 JSON 术语)“ sibling ”(在数据结构的同一级别),不同的缩进是您的危险信号,表明一切都不好。

更正大括号的位置,您可能打算编写更像这样的内容:
"Condition": {
    "StringEquals": { "ec2:ResourceTag/sf_env": "dev" },
    "StringEquals": { "ec2:Region": "us-west-2" }
}

这看起来更合理,尽管它几乎肯定是不正确的,因为反序列化的工作方式:现在你有两个 StringEquals键在同一个对象中,虽然 JSON 标准似乎没有禁止这种行为,但这种行为充其量是未定义的,并且许多或大多数反序列化的库会将上述解释为:
"Condition": {
    "StringEquals": {
        "ec2:Region": "us-west-2"
    }
}

可以合理地预期较晚的键及其值将取代相同的较早的键及其值。

这也是 JSONLint 解释它的方式。在一个 JSON 对象中,一个键只能有一个值——记住“值”意味着一个对象、数组、字符串、数字、 bool 值或空值。当存在多个值时,它必须正确地嵌套在内部结构中。

那么,正确的表达方式是什么?
"Condition": {
    "StringEquals": {
        "ec2:ResourceTag/sf_env": ["dev"],
        "ec2:Region": ["us-west-2"]
    }
}

Condition 值的对象有一把 key ,StringEquals ,其值是一个具有两个键的对象,ec2:ResourceTag/sf_envec2:Region ;这些键中的每一个都有一个包含一个或多个字符串的数组作为其值。

所以,不仅可以使用多个 StringEquals测试,如果需要,当这些值出现在我显示的数组中时,这些测试中的每一个也可以匹配多个值中的任何一个。例如,["dev","prod"]代替 ["dev"]将匹配 devprod .

如果每个值只有一个值,IAM 似乎只支持使用字符串而不是数组,例如"dev"更换 ["dev"] (这也是有效的 JSON)但我观察到的记录示例倾向于将其显示为我在上面记录的,如 { key1: [ "list" ], key2: ["list"] } ... 等等,如果您现在以这种方式对其进行格式化,如果您想稍后允许更多可能的值,它将更加直观。

关于amazon-web-services - 具有多个条件的 AWS IAM 策略语法错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32144428/

相关文章:

amazon-web-services - spark aws S3a ARN(亚马逊资源名称)IAM 角色

amazon-web-services - 如何访问cloudfront到s3存储桶对象简单url

amazon-web-services - AWS IAM s3 :prefix

amazon-web-services - 使用 boto3 进行 AWS Comprehend 时出现 IAM 权限错误

amazon-web-services - 用户 CloudFormer 所需的权限

amazon-web-services - 如何从 EC2 实例配置文件管理 EKS?

amazon-web-services - AWS EC2 IAM 角色访问在 S3 上被拒绝

amazon-web-services - CloudFormation 不会传播 EMR 的堆栈级标签

mysql - 如果不存在则创建表挂起

amazon-web-services - AWS Cloudformation - 在 Fn::Sub 中使用 AWS::NoValue