

# 排查 IAM 策略问题
<a name="troubleshoot_policies"></a>

[策略](access_policies.md)是 AWS 中的一个实体；在附加到身份或资源时，策略定义它们的权限。在主体（如用户）发出请求时，AWS 将评估这些策略。策略中的权限确定是允许还是拒绝请求。策略作为 JSON 文档存储在 AWS 中，它们作为*基于身份的策略* 附加到主体或作为*基于资源的策略* 附加到资源。您可以将基于身份的策略附加到主体（或身份），例如，IAM 组、用户或角色。基于身份的策略包括 AWS 托管策略、客户托管策略和内联策略。您可以在 AWS 管理控制台 中使用**可视化**和 **JSON** 编辑器选项创建和编辑客户管理型策略。在 AWS 管理控制台中查看策略时，您可以查看该策略授予的权限的摘要。您可以使用可视化编辑器和策略摘要帮助诊断和修复在管理 IAM policy 时遇到的常见错误。

请记住，所有 IAM policy 是使用以 [JavaScript 对象表示法](http://www.json.org) (JSON) 规则开头的语法存储的。您无需了解该语法，即可创建或管理您的策略。您可以在 AWS 管理控制台中使用可视化编辑器创建和编辑策略。要了解 IAM policy 中的 JSON 语法的更多信息，请参阅。[IAM JSON 策略语言的语法](reference_policies_grammar.md)

**IAM policy 故障排除主题**
+ [使用可视化编辑器排除故障](#troubleshoot_policies-viseditor)
  + [调整策略结构](#troubleshoot_viseditor-restructure)
  + [在可视化编辑器中选择资源 ARN](#troubleshoot_policies-resource-arn)
  + [在可视化编辑器中拒绝权限](#troubleshoot_policies-switch-deny)
  + [在可视化编辑器中指定多个服务](#troubleshoot_policies-multiple-services)
  + [在可视化编辑器中减小策略大小](#troubleshoot_policy-size)
  + [在可视化编辑器中修复无法识别的服务、操作或资源类型](#troubleshoot_policies-unrecognized-visual)
+ [排查策略摘要问题](#troubleshoot_policies-polsum)
  + [缺少策略摘要](#missing-policy-summary)
  + [摘要策略包含无法识别的服务、操作或资源类型](#unrecognized-services-actions)
  + [服务不支持 IAM policy 摘要](#unsupported-services-actions)
  + [我的策略未授予预期权限](#policy-summary-not-grant-permissions)
+ [策略管理故障排查](#troubleshoot_policies-policy-manage)
  + [在 IAM 账户中附加或分离策略](#troubleshoot_roles_cant-attach-detach-policy)
  + [根据您的 IAM 身份活动更改这些身份的策略](#troubleshoot_change-policies-based-on-activity)
+ [JSON 策略文档故障排查](#troubleshoot_policies-json)
  + [验证您的策略](#usepolicyvalidation)
  + [我在 JSON 编辑器中没有用于策略验证的权限](#nopermsforpolicyvalidation)
  + [多个 JSON 策略对象](#morethanonepolicyblock)
  + [多个 JSON Statement 元素](#morethanonestatement)
  + [在 JSON Statement 元素中具有多个 Effect、Action 或 Resource 元素](#duplicateelement)
  + [缺少 JSON Version 元素](#missing-version)

## 使用可视化编辑器排除故障
<a name="troubleshoot_policies-viseditor"></a>

在创建或编辑客户管理型策略时，您可以使用**可视化**编辑器中的信息帮助纠正策略中的错误。要查看使用可视化编辑器创建策略的示例，请参阅[控制对身份的访问](access_controlling.md#access_controlling-identities)。

### 调整策略结构
<a name="troubleshoot_viseditor-restructure"></a>

在创建策略时，AWS 将在存储之前验证、处理和转换该策略。检索策略后，AWS 无需更改权限即可将其转换回人类可读的格式。这可能会导致您在策略可视化编辑器或 **JSON** 选项卡中看到的内容有所不同。
+ 可以添加、删除或重新排序可视化编辑器权限块，并且可以优化块内的内容。
+ 在 **JSON** 选项卡中，可以删除不太重要的空格，并且可以将 JSON 映射中的元素重新排序。此外，可以将主体元素中的 AWS 账户 ID 替换为 AWS 账户根用户 的 Amazon 资源名称（ARN）。

由于可能发生这些更改，不应以字符串形式来比较 JSON 策略文档。

在 AWS 管理控制台 中创建客户管理型策略时，您可以选择完全在 **JSON** 编辑器中工作。如果从未在**可视化**编辑器中更改策略，并未从 **JSON** 选项卡中选择**下一步**，则不太可能会调整策略结构。当您使用**可视化**编辑器时，IAM 可能会重构策略以优化其外观。该结构调整仅在您的编辑会话中进行，不会自动进行保存。

如果在您的编辑会话中调整您的策略结构，则 IAM 根据以下情况确定是否保存结构调整：


| 使用此编辑器选项 | 如果编辑您的策略 | 然后从此选项卡中选择***下一步*** | 在选择***保存更改***时 | 
| --- | --- | --- | --- | 
| 可视化 | 已编辑 | 可视化 | 将调整策略结构 | 
| 可视化 | 已编辑 | JSON | 将调整策略结构 | 
| 可视化 | 未编辑 | 可视化 | 将调整策略结构 | 
| JSON | 已编辑 | 可视化 | 将调整策略结构 | 
| JSON | 已编辑 | JSON | 不会更改策略结构 | 
| JSON | 未编辑 | JSON | 不会更改策略结构 | 

IAM 可能会调整复杂策略或具有权限块或语句以允很多个服务、资源类型或条件键的策略的结构。

### 在可视化编辑器中选择资源 ARN
<a name="troubleshoot_policies-resource-arn"></a>

在使用可视化编辑器创建或编辑策略时，您必须先选择一个服务，然后从该服务中选择操作。如果选择的服务和操作支持选择[特定的资源](access_controlling.md#access_controlling-resources)，可视化编辑器将列出支持的资源类型。然后，您可以选择**添加 ARN** 以提供有关您的资源的详细信息。您可以从以下选项中进行选择以添加资源类型的 ARN。
+ **使用 ARN 生成器**：根据资源类型，您可能会看到用于生成 ARN 的不同字段。您也可以选择**任意**，以便为指定的设置的任何值提供权限。例如，如果选择 Amazon EC2 **Read**（读取）访问级别组，则您的策略中的操作支持 `instance` 资源类型。为您的资源提供**区域**、**账户**和**实例 ID** 值。如果提供您的账户 ID，并为区域和实例 ID 选择**任意**，则策略为您账户中的任何实例授予权限。
+ **键入或粘贴 ARN** - 您可以按 [Amazon Resource Name (ARN)](reference_identifiers.md#identifiers-arns) 指定资源。您可以在 ARN 的任何字段中包含通配符 (**\$1**)（每对冒号之间）。有关更多信息，请参阅 [IAM JSON 策略元素：Resource](reference_policies_elements_resource.md)。

### 在可视化编辑器中拒绝权限
<a name="troubleshoot_policies-switch-deny"></a>

默认情况下，使用可视化编辑器创建的策略允许执行选择的操作。要拒绝选择的操作，请选择**切换到拒绝权限**。由于*默认拒绝*请求，建议您仅允许用户所需的操作和资源的权限。只有在要覆盖其他语句或策略单独允许的权限时，您才应创建拒绝语句。我们建议您将拒绝权限数限制为最低，因为它们可能会增加解决权限问题的难度。有关 IAM 如何评估策略逻辑的更多信息，请参阅 [策略评估逻辑](reference_policies_evaluation-logic.md)。

**注意**  
默认情况下，仅 AWS 账户根用户有权访问该账户中的所有资源。因此，如果未以根用户身份登录，您必须具有策略授予的权限。

### 在可视化编辑器中指定多个服务
<a name="troubleshoot_policies-multiple-services"></a>

在使用可视化编辑器构建策略时，您每次只能选择一个服务。这是最佳实践，因为可视化编辑器允许您从该服务的操作中进行选择。然后，您可以从该服务和选定的操作支持的资源中进行选择。这样，就可以更轻松地创建策略和进行故障排除。

您还可以使用通配符（\$1）手动指定多个服务。例如，键入 **Code\$1**，以便为以 `Code` 开头的所有服务（如 `CodeBuild` 和 `CodeCommit`）提供权限。不过，您必须随后键入操作和资源 ARN 以完成您的策略。此外，在保存您的策略时，可能会[调整](#troubleshoot_viseditor-restructure)策略结构以在单独的权限块中包含每个服务。

或者，要在服务中使用 JSON 语法（如通配符），请使用 **JSON** 编辑器选项创建、编辑和保存策略。

### 在可视化编辑器中减小策略大小
<a name="troubleshoot_policy-size"></a>

在使用可视化编辑器创建策略时，IAM 将创建一个 JSON 文档以存储您的策略。您可以切换到 **JSON** 编辑器选项以查看该文档。如果该 JSON 文档超过策略的大小限制，可视化编辑器将显示错误消息。您将无法查看和保存该策略。要查看 IAM 的托管策略大小限制，请参阅 [IAM 和 STS 字符限制](reference_iam-quotas.md#reference_iam-quotas-entity-length)。

要在可视化编辑器中减小您的策略大小，请编辑您的策略或将权限块移到另一个策略。错误消息包括策略文档中包含的字符数。您可以使用此信息来帮助缩减策略大小。

### 在可视化编辑器中修复无法识别的服务、操作或资源类型
<a name="troubleshoot_policies-unrecognized-visual"></a>

您可能会在可视化编辑器中看到一条警告，指出您的策略包含无法识别的服务、操作或资源类型。

**注意**  
IAM 将检查支持策略摘要的服务的服务名称、操作和资源类型。但是，您的策略摘要可能包含不存在的资源值或条件。始终通过[策略模拟器](access_policies_testing-policies.md)测试您的策略。

如果您的策略包含无法识别的服务、操作或资源类型，则存在以下错误之一：
+ **预览服务** - 处于预览状态的服务不支持可视化编辑器。如果您参与预览，则必须手动键入操作和资源 ARN 以完成您的策略。您可以忽略任何警告并继续。或者，您也可以选择 **JSON** 编辑器选项以键入或粘贴 JSON 策略文档。
+ **自定义服务** - 自定义服务不支持可视化编辑器。如果您使用自定义服务，则必须手动键入操作和资源 ARN 以完成您的策略。您可以忽略任何警告并继续。或者，您也可以选择 **JSON** 编辑器选项以键入或粘贴 JSON 策略文档。
+ **服务不支持可视化编辑器**：如果您的策略包含不支持可视化编辑器的已正式发布（GA）的服务，则必须手动键入操作和资源 ARN 以完成您的策略。您可以忽略任何警告并继续。或者，您也可以选择 **JSON** 编辑器选项以键入或粘贴 JSON 策略文档。

  公开提供服务是公开发布的服务，不是预览或自定义服务。如果无法识别的服务是公开提供的，并且名称拼写正确，则该服务不支持可视化编辑器。要了解如何请求 GA 服务的可视化编辑器或策略摘要支持，请参阅[服务不支持 IAM policy 摘要](#unsupported-services-actions)。
+ **操作不支持可视化编辑器**：如果您的策略包含的受支持服务具有不支持的操作，则必须手动键入操作和资源 ARN 以完成您的策略。您可以忽略任何警告并继续。或者，您也可以选择 **JSON** 编辑器选项以键入或粘贴 JSON 策略文档。

  如果您的策略包含的受支持服务具有不支持的操作，则该服务不完全支持可视化编辑器。要了解如何请求 GA 服务的可视化编辑器或策略摘要支持，请参阅[服务不支持 IAM policy 摘要](#unsupported-services-actions)。
+ **资源类型不支持可视化编辑器** - 如果您的策略包含的受支持操作具有不支持的资源类型，您可以忽略该警告并继续。不过，IAM 无法确认是否包含所有选定操作的资源，并且您可能会看到额外的警告。
+ **拼写错误** - 在可视化编辑器中手动键入服务、操作或资源时，您创建的策略可能会包含拼写错误。建议您使用可视化编辑器，从服务和操作列表中进行选择。然后，根据提示完成资源部分。如果服务不完全支持可视化编辑器，您可能需要手动键入某些策略部分。

  如果您确定自己的策略不包含上述任何错误，那么您的策略可能包含拼写错误。检查有无以下问题：
  + 服务、操作和资源类型名称拼写错误，例如 `s2` 而不是 `s3` 或 `ListMyBuckets` 而不是 `ListAllMyBuckets`
  + ARN 中不必要的文本，例如 `arn:aws:s3: : :*`
  + 操作中缺少冒号，例如 `iam.CreateUser`

  您可以选择**下一步**以查看策略摘要并确认策略是否提供所需的权限，从而对可能包含拼写错误的策略进行评估。然后，确认策略是否提供所需的权限。

## 排查策略摘要问题
<a name="troubleshoot_policies-polsum"></a>

您可以诊断并解决与策略摘要相关的问题。

### 缺少策略摘要
<a name="missing-policy-summary"></a>

IAM 控制台中提供了*策略摘要*表，这些表总结了策略中对每个服务允许或拒绝的访问级别、资源和条件。策略在三个表中概括：[策略摘要](access_policies_understand-policy-summary.md)、[服务摘要](access_policies_understand-service-summary.md)和[操作摘要](access_policies_understand-action-summary.md)。*策略摘要*表包括由所选策略定义的服务列表和权限摘要。您可以在策略的**策略详细信息**页面查看附加到实体的任何策略的[策略摘要](access_policies_understand.md)。可以在 **Policies** 页面上查看托管策略的策略摘要。如果 AWS 无法呈现策略摘要，您将看到 JSON 策略文档和以下错误：

**无法为此策略生成摘要。您仍然可以查看或编辑 JSON 策略文档。**

如果您的策略不包含摘要，则已发生下列错误之一：
+ **不支持的策略元素** - IAM 不支持为包含以下[策略元素](reference_policies_elements.md)之一的策略生成策略摘要：
  + `Principal`
  + `NotPrincipal`
  + `NotResource`
+ **无策略权限** - 如果策略不提供任何有效权限，则无法生成策略摘要。例如，如果策略包含元素 `"NotAction": "*"` 的单个语句，则它将授予对除“所有操作”(\$1) 之外的所有操作的访问权限。这意味着，它未授予对任何内容的 `Deny` 或 `Allow` 访问权限。
**注意**  
在使用这些策略元素（如 `NotPrincipal`、`NotAction` 和 `NotResource`）时应谨慎。有关使用策略元素的信息，请参阅[IAM JSON 策略元素参考](reference_policies_elements.md)。

  如果您提供不匹配的服务和资源，则可能会创建一个不提供有效权限的策略。您指定一个服务中的操作和另一个服务中的资源时，可能会发生这种情况。在这种情况下，仍然会出现策略摘要。表示有问题的唯一迹象是，摘要中的资源列可能包含来自不同服务的资源。如果此列包含不匹配的资源，那么您应该查看策略中是否有错误。使用[策略模拟器](access_policies_testing-policies.md)测试您的策略，以更好地了解该策略。

### 摘要策略包含无法识别的服务、操作或资源类型
<a name="unrecognized-services-actions"></a>

在 IAM 控制台中，如果[策略摘要](access_policies_understand.md)包含警告符号（![\[Warning hazard sign icon with yellow triangle background.\]](http://docs.aws.amazon.com/zh_cn/IAM/latest/UserGuide/images/console-alert-icon.console.png)），则策略可能包含无法识别的服务、操作或资源类型。要了解策略摘要内的警告，请参阅[策略摘要（服务列表）](access_policies_understand-policy-summary.md)。

**注意**  
IAM 将检查支持策略摘要的服务的服务名称、操作和资源类型。但是，您的策略摘要可能包含不存在的资源值或条件。始终通过[策略模拟器](access_policies_testing-policies.md)测试您的策略。

如果您的策略包含无法识别的服务、操作或资源类型，则存在以下错误之一：
+ **预览服务** - 处于预览状态的服务不支持策略摘要。
+ **自定义服务** - 自定义服务不支持策略摘要。
+ **服务不支持摘要** - 如果您的策略包括不支持策略摘要的公开发布 (GA) 服务，则该服务将包含在策略摘要表的 **Unrecognized services**（无法识别的服务）部分。公开提供服务是公开发布的服务，不是预览或自定义服务。如果无法识别的服务是公开提供的，并且名称拼写正确，则该服务不支持 IAM policy 摘要。要了解如何请求 GA 服务的策略摘要支持，请参阅[服务不支持 IAM policy 摘要](#unsupported-services-actions)。
+ **操作不支持摘要** - 如果您的策略包含的受支持服务具有不支持的操作，则该操作将包含在服务摘要表的 **Unrecognized actions**（无法识别的操作）部分。要了解服务摘要内的警告，请参阅[服务摘要（操作列表）](access_policies_understand-service-summary.md)。
+ **资源类型不支持摘要** - 如果您的策略包含的受支持操作具有不支持的资源类型，则该资源将包含在服务摘要表的 **Unrecognized resource types**（无法识别的资源类型）部分。要了解服务摘要内的警告，请参阅[服务摘要（操作列表）](access_policies_understand-service-summary.md)。
+ **错字** — AWS 检查 JSON 语法是否正确，并且策略不在[策略验证](access_policies_policy-validator.md)中包含错字或其他错误。

**注意**  
作为[最佳实践](best-practices.md)，我们建议您使用 IAM Access Analyzer 验证您的 IAM policy，以确保权限的安全性和功能性。我们建议您打开现有策略，查看并解决任何策略验证建议。

### 服务不支持 IAM policy 摘要
<a name="unsupported-services-actions"></a>

IAM 策略摘要或可视化编辑器可能不支持已正式发布（GA）的服务或操作。公开提供服务是公开发布的服务，不是预览或自定义服务。如果无法识别的服务是公开提供的，并且名称拼写正确，则该服务不支持这些功能。如果您的策略包含的受支持服务具有不受支持的操作，则表示该服务不完全支持 IAM policy 摘要。

**请求服务添加 IAM policy 摘要或可视化编辑器支持**

1. 登录 AWS 管理控制台，然后通过以下网址打开 IAM 控制台：[https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)。

1. 找到包含不支持的服务的策略：
   + 如果该策略是托管策略，请在导航窗格中选择 **Policies**。在策略列表中，选择要查看的策略的名称。
   + 如果该策略是附加到用户的内联策略，请在导航窗格中选择 **Users**。在用户列表中，选择要查看其策略的用户的名称。在用户的策略表中，展开您要查看的策略摘要的标题。

1. 在 AWS 管理控制台页脚左侧，选择 **Feedback (反馈)**。在 **IAM 反馈**框中，键入 **I request that the <ServiceName> service add support for IAM policy summaries and the visual editor**。如果希望多个服务支持摘要，请键入 **I request that the <ServiceName1>, <ServiceName2>, and <ServiceName3> services add support for IAM policy summaries and the visual editor**。

**请求服务为缺失的操作增加 IAM policy 摘要支持**

1. 登录 AWS 管理控制台，然后通过以下网址打开 IAM 控制台：[https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)。

1. 找到包含不支持的服务的策略：
   + 如果该策略是托管策略，请在导航窗格中选择 **Policies**。在策略列表中，选择要查看的策略的名称。
   + 如果该策略是附加到用户的内联策略，请在导航窗格中选择 **Users**。在用户列表中，选择要查看其策略的用户的名称。在用户的策略表中，选择要查看的策略的名称以展开策略摘要。

1. 在策略摘要中，选择包含不支持操作的服务的名称。

1. 在 AWS 管理控制台页脚左侧，选择 **Feedback (反馈)**。在 **IAM 反馈**框中，键入 **I request that the <ServiceName> service add IAM policy summary and the visual editor support for the <ActionName> action**。如果要报告多个不支持的操作，请键入 **I request that the <ServiceName> service add IAM policy summary and the visual editor support for the <ActionName1>, <ActionName2>, and <ActionName3> actions**。

要请求包含缺少操作的不同服务，请重复最后三个步骤。

### 我的策略未授予预期权限
<a name="policy-summary-not-grant-permissions"></a>

要给用户、组、角色或资源指定权限，您必须创建一个*策略*，它是一个定义权限的文档。策略文档包含以下元素：
+ **效果** - 策略允许还是拒绝访问
+ **操作** - 策略允许或拒绝的操作的列表
+ **资源** - 作为操作目标的资源的列表
+ **条件**（可选）- 策略在哪些情况下授予权限

要了解上述及其他策略元素，请参阅[IAM JSON 策略元素参考](reference_policies_elements.md)。

要授予访问权限，策略必须定义具有支持资源的操作。如果策略还包含条件，该条件必须包含[全局条件键](reference_policies_condition-keys.md)或必须应用至操作。要了解操作支持哪些资源，请参阅服务的 [AWS 文档](https://docs.aws.amazon.com/)。要了解操作支持哪些条件，请参阅 [AWS 服务的操作、资源或条件键](reference_policies_actions-resources-contextkeys.html)。

请检查策略是否定义了未授予权限的操作、资源或条件。使用 IAM 控制台查看您的策略的[策略摘要](access_policies_understand-policy-summary.md)，网址为 [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)。您可以使用策略摘要识别和纠正策略中的问题。

对于元素不按 IAM policy 中的定义授予权限的情况，原因可能有：
+ [**定义了操作，但没有适用的资源**](#mismatch_action-no-resource)
+ [**定义了资源，但没有适用的操作**](#mismatch_resource-no-action)
+ [**定义了条件，但没有适用的操作**](#mismatch_condition-no-match)

要查看包含警告的策略摘要的示例，请参阅[策略摘要（服务列表）](access_policies_understand-policy-summary.md)。

#### 定义了操作，但没有适用的资源
<a name="mismatch_action-no-resource"></a>

下面的策略定义了所有 `ec2:Describe*` 操作和一个特定资源。这些操作都不支持资源级权限，因而未授予任何 `ec2:Describe` 操作。资源级权限意味着操作支持使用策略的 [`Resource`](reference_policies_elements_resource.md) 元素中的 [ARN](reference_identifiers.md#identifiers-arns) 的资源。如果操作不支持资源级权限，则策略中的语句必须在 `*` 元素中使用通配符 (`Resource`)。要了解哪些服务支持资源级权限，请参阅[使用 IAM 的 AWS 服务](reference_aws-services-that-work-with-iam.md)。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "ec2:Describe*",
            "Resource": "arn:aws:ec2:us-east-2:111122223333:instance/*"
        }
    ]
}
```

------

此策略未提供任何权限，并且策略摘要包含以下错误：

`This policy does not grant any permissions. To grant access, policies must have an action that has an applicable resource or condition.`

要修复该策略，必须在 `*` 元素中使用 `Resource`。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [{
        "Effect": "Allow",
        "Action": "ec2:Describe*",
        "Resource": "*"
    }]
}
```

------

#### 定义了资源，但没有适用的操作
<a name="mismatch_resource-no-action"></a>

下面的策略定义了 Amazon S3 存储桶资源，但不包含可在该资源上执行的 S3 操作。该策略还向所有 Amazon CloudFront 操作授予完全访问权限。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
        "Effect": "Allow",
        "Action": "cloudfront:*",
        "Resource": [
            "arn:aws:cloudfront:*",
            "arn:aws:s3:::amzn-s3-demo-bucket"
        ]
        }
    ]
}
```

------

该策略为所有 CloudFront 操作提供权限。但由于策略定义了 S3 `amzn-s3-demo-bucket` 资源而未定义任何 S3 操作，策略摘要将包含以下警告：

`This policy defines some actions, resources, or conditions that do not provide permissions. To grant access, policies must have an action that has an applicable resource or condition.`

要修复该策略以提供 S3 存储桶权限，必须定义可在存储桶资源上执行的 S3 操作。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "cloudfront:*",
                "s3:CreateBucket",
                "s3:ListBucket*",
                "s3:PutBucket*",
                "s3:GetBucket*"
            ],
            "Resource": [
                "arn:aws:cloudfront:*",
                "arn:aws:s3:::amzn-s3-demo-bucket"
            ]
        }
    ]
}
```

------

此外，要修复该策略以只提供 CloudFront 权限，应删除 S3 资源。

#### 定义了条件，但没有适用的操作
<a name="mismatch_condition-no-match"></a>

如果 S3 前缀等于 `custom` 且版本 ID 等于 `1234`，下面的策略为所有 S3 资源定义两个 Amazon S3 操作。但是，`s3:VersionId` 条件键用于对象版本标记，不受所定义的存储桶操作的支持。要了解操作支持哪些条件，请参阅 [AWS 服务的操作、资源和条件键](https://docs.aws.amazon.com/service-authorization/latest/reference/reference_policies_actions-resources-contextkeys.html)，然后选择服务以查看条件键的服务文档。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucketVersions",
                "s3:ListBucket"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "s3:prefix": [
                        "custom"
                    ],
                    "s3:VersionId": [
                        "1234"
                    ]
                }
            }
        }
    ]
}
```

------

如果存储桶名称包含 `s3:ListBucketVersions` 前缀，该策略为 `s3:ListBucket` 操作和 `custom` 操作提供权限。但是，由于任何定义的操作都不支持 `s3:VersionId` 条件，策略摘要将包含以下错误：

`This policy does not grant any permissions. To grant access, policies must have an action that has an applicable resource or condition.`

要修复该策略以使用 S3 对象版本标记，就必须定义支持 `s3:VersionId` 条件键的 S3 操作。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucketVersions",
                "s3:ListBucket",
                "s3:GetObjectVersion"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "s3:prefix": [
                        "custom"
                    ],
                    "s3:VersionId": [
                        "1234"
                    ]
                }
            }
        }
    ]
}
```

------

此策略为策略中的每个操作和条件提供权限。但由于不存在单一操作匹配两个条件的情况，策略不提供任何权限。为解决这一问题，您必须创建两个单独的语句，每个语句只包含具有要应用条件的操作。

要修复此策略，请创建两个语句。第一个语句包含支持 `s3:prefix` 条件的操作，第二个语句包含支持 `s3:VersionId` 条件的操作。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucketVersions",
                "s3:ListBucket"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "s3:prefix": "custom"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": "s3:GetObjectVersion",
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "s3:VersionId": "1234"
                }
            }
        }
    ]
}
```

------

## 策略管理故障排查
<a name="troubleshoot_policies-policy-manage"></a>

您可以诊断并解决与策略管理相关的问题。

### 在 IAM 账户中附加或分离策略
<a name="troubleshoot_roles_cant-attach-detach-policy"></a>

有些 AWS 托管策略与服务关联。这些策略仅用于该服务的某个[服务相关角色](id_roles.md#iam-term-service-linked-role)。在 IAM 控制台中查看**策略详细信息**页面时，该页面包含一个横幅，指示该策略与服务关联。您不能将该策略附加到 IAM 内的用户、组或角色。当您为服务创建服务相关角色时，该策略会自动附加到您的新角色。由于策略是必需的，因此您无法将策略与服务相关角色分离。

### 根据您的 IAM 身份活动更改这些身份的策略
<a name="troubleshoot_change-policies-based-on-activity"></a>

您可以根据 IAM 身份（用户、组和角色）的活动更新其策略。要执行此操作，请在 CloudTrail **事件历史记录**中查看您账户的事件。CloudTrail 事件日志包含详细的事件信息，您可以用来更改策略的权限。

**用户或角色尝试在 AWS 中执行操作，该请求被拒绝。**  
考虑用户或角色是否应具有执行该操作的权限。如果应该具有，您可以添加操作，甚至添加它们试图根据其策略访问的资源的 ARN。

**用户或角色具有其不使用的权限。**  
考虑从其策略中删除这些权限。请确保您的策略仅授予执行必需的操作所需要的[最低权限](best-practices.md#grant-least-privilege)。

有关使用 CloudTrail 的更多信息，请参阅 *AWS CloudTrail 用户指南*中的[在 CloudTrail 控制台中查看 CloudTrail 事件](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/view-cloudtrail-events-console.html)。

## JSON 策略文档故障排查
<a name="troubleshoot_policies-json"></a>

您可以诊断并解决与 JSON 策略文档相关的问题。

### 验证您的策略
<a name="usepolicyvalidation"></a>

 当您创建或编辑 JSON 策略时，IAM 可以执行策略验证以帮助您创建有效的策略。IAM 可识别 JSON 语法错误，而 IAM Access Analyzer 将提供额外的策略检查和建议，以帮助您进一步优化策略。要了解策略验证的更多信息，请参阅 [IAM 策略验证](access_policies_policy-validator.md)。要了解有关 IAM Access Analyzer 策略检查和可操作建议的更多信息，请参阅 [IAM Access Analyzer 策略验证](https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-policy-validation.html)。

### 我在 JSON 编辑器中没有用于策略验证的权限
<a name="nopermsforpolicyvalidation"></a>

在 AWS 管理控制台 中，如果您没有查看 IAM Access Analyzer 策略验证结果的权限，则可能会收到以下错误：

`You need permissions. You do not have the permissions required to perform this operation. Ask your administrator to add permissions.`

要纠正该错误，请要求管理员为您添加 `access-analyzer:ValidatePolicy` 权限。

### 多个 JSON 策略对象
<a name="morethanonepolicyblock"></a>

IAM 策略必须仅包含一个 JSON 对象。可通过在两旁放置 \$1 \$1 括号来表示对象。您可以通过在外部对中嵌入额外的 \$1\$1 大括号，将其他对象嵌套在 JSON 对象中。策略必须仅包含一对最外层的 \$1\$1 大括号。以下示例不正确，因为它在顶层包含两个对象 (以*红色*标示)：

------
#### [ JSON ]

****  

```
{
      "Version":"2012-10-17",		 	 	 
      "Statement": 
      {
         "Effect":"Allow",
         "Action":"ec2:Describe*",
         "Resource":"*"
      }
    }
    { 
      "Statement": {
         "Effect": "Allow",
         "Action": "s3:*",
         "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/*"
      }
    }
```

------

不过，您可以使用正确的策略语法来实现上面示例的意图。可以将两个数据块合并到单个 `Statement` 元素中，而不是包含两个完整的策略对象（每个都有自己的 `Statement` 元素）。`Statement` 元素将两个对象组成的数组作为其值，如以下示例所示 (以**粗体**标示)：

------
#### [ JSON ]

****  

```
{
      "Version":"2012-10-17",		 	 	 
      "Statement": [
        {
          "Effect": "Allow",
          "Action": "ec2:Describe*",
          "Resource":"*"
        },
        {
          "Effect": "Allow",
          "Action": "s3:*",
          "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/*"
        }
      ]
    }
```

------

### 多个 JSON Statement 元素
<a name="morethanonestatement"></a>

此错误乍一看似乎是由上一部分变化而来的。但是，它在语法上是不同类型的错误。在以下示例中，顶层只有一个策略对象，由单个 \$1 \$1 括号对表示。但是，该对象包含两个 `Statement` 元素。

 一个 IAM policy 只能包含一个 `Statement` 元素，名称 (`Statement`) 在冒号左侧，它的值在冒号右侧。`Statement` 元素的值必须是对象，以 \$1 \$1 括号表示，其中包含一个 `Effect` 元素、一个 `Action` 元素和一个 `Resource` 元素。以下示例不正确，因为策略对象包含两个 `Statement` 元素 (以*红色*标示)：

------
#### [ JSON ]

****  

```
{
      "Version":"2012-10-17",		 	 	 
      "Statement": {
        "Effect": "Allow",
        "Action": "ec2:Describe*",
        "Resource": "*"
      },
      "Statement": {
        "Effect": "Allow",
        "Action": "s3:*",
        "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/*"
      }
    }
```

------

值对象可以是多个值对象组成的数组。为解决此问题，可使用对象数组将两个 `Statement` 元素组合为一个元素，如下例所示 (以**粗体**标示)：

------
#### [ JSON ]

****  

```
{
      "Version":"2012-10-17",		 	 	 
      "Statement": [
        {
          "Effect": "Allow",
          "Action": "ec2:Describe*",
          "Resource":"*"
        },
        {
          "Effect": "Allow",
          "Action": "s3:*",
          "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/*"
        }
     ]
    }
```

------

`Statement` 元素的值是对象数组。此示例中的数组包含两个对象，每个对象自身是 `Statement` 元素的正确值。数组中的每个对象之间用逗号隔开。

### 在 JSON Statement 元素中具有多个 Effect、Action 或 Resource 元素
<a name="duplicateelement"></a>

在 `Statement` 名称/值对的值侧，对象只能包含一个 `Effect` 元素、一个 `Action` 元素和一个 `Resource` 元素。以下策略不正确，因为其在 `Statement` 中有两个 `Effect` 元素：

------
#### [ JSON ]

****  

```
{
      "Version":"2012-10-17",		 	 	 
      "Statement": {
        "Effect": "Deny",
        "Effect": "Allow",     
        "Action": "ec2:* ",
        "Resource": "*"
      }
    }
```

------

**注意**  
策略引擎不允许新的或已编辑的策略中出现此类错误。但是，策略引擎仍然允许在引擎更新之前保存的策略。现有策略的错误行为如下所示：  
多个 `Effect` 元素：仅遵循最后一个 `Effect` 元素。忽略其他元素。
多个 `Action` 元素：所有 `Action` 元素进行内部合并，被视为单个列表。
多个 `Resource` 元素：所有 `Resource` 元素进行内部合并，被视为单个列表。
策略引擎不允许您保存任何有 语法 错误的策略。请先更正策略中的错误，然后再保存。查看并更正针对您的策略的任何[策略验证](access_policies_policy-validator.md)建议。

 在每种情况下，解决方案都是删除不正确的多余元素。对于 `Effect` 元素，这十分简单：如果您希望前面的示例*拒绝* 针对 Amazon EC2 实例的权限，则必须从策略中删除行 `"Effect": "Allow",`，如下所示：

------
#### [ JSON ]

****  

```
{
      "Version":"2012-10-17",		 	 	 
      "Statement": {
        "Effect": "Deny",
        "Action": "ec2:*",
        "Resource": "*"
      }
    }
```

------

但是，如果重复元素是 `Action` 或 `Resource`，则解决方法可能会更加复杂。您可能需要向多个操作允许 (或拒绝) 权限，或者需要控制对多个资源的访问。例如，以下示例不正确，因为它有多个 `Resource` 元素 (以*红色*标示)：

------
#### [ JSON ]

****  

```
{
      "Version":"2012-10-17",		 	 	 
      "Statement": {
        "Effect": "Allow",
        "Action": "s3:*",
        "Resource": "arn:aws:s3:::amzn-s3-demo-bucket",
        "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/*"
      }
    }
```

------

`Statement` 元素的值对象中的每个必需元素都只能出现一次。解决方案是将每个值置于数组中。以下示例通过将两个单独的 Resource 元素合并为一个以数组为值对象的 `Resource` 元素来对此进行说明 (以**粗体**标示)：

------
#### [ JSON ]

****  

```
{	
      "Version":"2012-10-17",		 	 	 
      "Statement": {
        "Effect": "Allow",
        "Action": "s3:*",
        "Resource": [
          "arn:aws:s3:::amzn-s3-demo-bucket",
          "arn:aws:s3:::amzn-s3-demo-bucket/*"
        ]
      }
    }
```

------

### 缺少 JSON Version 元素
<a name="missing-version"></a>

`Version` 策略元素与策略版本不同。`Version` 策略元素用在策略之中，用于定义策略语言的版本。相比之下，当您在 IAM 中更改客户管理型策略时，将创建一个策略版本。已更改的策略不会覆盖现有策略。而是由 IAM 创建新的托管策略版本。要了解 `Version` 策略元素的更多信息，请参阅[IAM JSON 策略元素：Version](reference_policies_elements_version.md)。要了解策略版本的更多信息，请参阅[IAM policy 版本控制](access_policies_managed-versioning.md)。

随着 AWS 功能的发展，为支持这些功能，IAM policy 增加了新的功能。有时，策略语法更新包括新版本号。如果您在策略中使用策略语法的较新功能，则必须向策略分析引擎告知所使用的版本。默认策略版本是“2008-10-17”。如果要使用之后引入的任何策略功能，则必须指定支持所需功能的版本号。我们建议*始终* 包含最新的策略语法版本号 (目前为 `"Version": "2012-10-17"`)。例如，以下策略是不正确的，因为它在资源的 ARN 中使用 `${...}` 策略变量。但是，它无法指定支持该策略变量的策略语法版本（以*红色* 标示）：

```
{
  "Statement": 
  {
    "Action": "iam:*AccessKey*",
    "Effect": "Allow",
    "Resource": "arn:aws:iam::123456789012:user/${aws:username}"
  }
}
```

通过在策略顶层添加值为 `2012-10-17`（支持策略变量的第一个 IAM API 版本）的 `Version` 元素，可解决此问题（以**粗体**标示）：

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": 
  {
    "Action": "iam:*AccessKey*",
    "Effect": "Allow",
    "Resource": "arn:aws:iam::123456789012:user/${aws:username}"
  }
}
```

------