【问题标题】:AWS IAM Policy Grammar Error with Multiple Conditions具有多个条件的 AWS IAM 策略语法错误
【发布时间】:2019-02-16 13:05:20
【问题描述】:

根据 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"
            }
          }
       }
    }
]

}

【问题讨论】:

  • 在这里吐槽,但看起来每个语句中第一个 StringEquals 之后的大括号可能没有在正确的时间关闭?
  • 大括号没问题,在哪里。 json 这样不敏感。我认为问题在于我如何编写多个条件和键值。第一次尝试这个。我可以让 1 个条件检查正常工作。 docs.aws.amazon.com/IAM/latest/UserGuide/…docs.aws.amazon.com/IAM/latest/UserGuide/policies-grammar.html
  • @HyperAnthony 证明是绝对正确的。当然,只要你不小心想出了一个也是有效 JSON 的结构,JSON 对此并不“敏感”——这就是这里发生的情况——但是键和值明显不对齐,使序列化陷入混乱.解决该问题会发现第二个问题,其中对象具有重复的键,这可能会导致某些值存储在位桶中,而不是存储在行另一端的反序列化结构中。

标签: amazon-web-services amazon-iam


【解决方案1】:

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

看看你最后的情况,你写道:

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

请注意:由于以下是从较大的 JSON 对象中提取的键/值 sn-ps,因此您必须将它们中的每一个嵌套在一对额外的外部 { 大括号 } 中,以便 JSONLint 到当在没有周围结构的情况下自行评估时,解析它,并且确实让它成为一个有效的 JSON 表示。在测试创建示例时,我在每种情况下都将它们添加到 JSONLint 输入中,并将它们从输出中删除,希望是为了清楚起见。

JSONLint 重新格式化上述内容,以向您展示您正在交流的内容:

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

JSON 的优势在于其简单的结构和约束:它具有 { 对象 }(键/值对,其中键是字符串,值恰好是在任何地方提到的任何类型的事物之一这句话)...[数组](值列表)..."字符串"...数字(未引用)...布尔值(true和false,未引用) ... 和 null(null,未引用)。

StringEquals,正如你在上面所表达的那样,是一个有两个键的对象,ec2:ResourceTag/sf_env(它的值是一个字符串)......和StringEquals(第二次出现,它有另一个嵌套对象作为它的值)。

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

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

更正大括号的位置,您可能打算写一些更像这样的东西:

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

这看起来更合理,尽管它仍然几乎可以肯定是不正确的,因为反序列化的工作方式:现在您在同一个对象中有两个 StringEquals 键,虽然 JSON 标准似乎没有禁止这样做,但这种行为是未定义的充其量,许多或大多数反序列化它的库会将上述内容解释为:

"Condition": {
    "StringEquals": {
        "ec2:Region": "us-west-2"
    }
}

可以合理地预期以后的键和它们的值会取代相同的早期键和它们的值。

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

那么,正确的表示是什么?

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

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

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

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

【讨论】:

  • tyvm 获取详细答案。我是 json 新手并编写这些策略。我将使用数组更新我的策略。这对于理解 json 的工作原理非常有帮助。
【解决方案2】:

我最近遇到了这个问题。以下是您将如何构建它:

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

【讨论】:

    【解决方案3】:

    JSON 中不能有两个 StringEquals。我使用 StringLike 作为解决方法。这个post 帮助我解决了这个问题。我的策略现在具有正确的 AWS 语法!

    {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "ec2:*",
            "Resource": "*",
            "Condition": {
                 "StringEquals": {
                 "ec2:ResourceTag/sf_env": "dev"
                 },
                 "StringLike": {"ec2:Region": "us-west-2"
              }
            }     
        },
        {
            "Effect": "Allow",
            "Action": "rds:*",
            "Resource": "*",
            "Condition": {
              "StringEquals": { 
                  "ec2:ResourceTag/sf_env": "dev"
              },
              "StringLike": { 
                  "ec2:Region": "us-west-2"
                }
              }
        },
        {
            "Sid": "AllowHealthCheckOnly",
            "Effect": "Allow",
            "Action": "elasticloadbalancing:Describe*",
            "Resource": "*",
            "Condition": {
                "StringEquals":{ 
                    "ec2:ResourceTag/sf_env": "dev"
            }, 
                "StringLike":{ 
                    "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"
              },
                 "StringLike": { "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"
                },
                "StringLike": { "ec2:Region": "us-west-2"
                }
              }
        }
    ]
    

    }

    【讨论】:

      猜你喜欢
      • 2020-01-23
      • 1970-01-01
      • 2017-11-26
      • 2021-07-31
      • 1970-01-01
      • 2020-11-09
      • 2020-11-11
      • 2012-11-23
      • 2021-03-06
      相关资源
      最近更新 更多