介绍
策略迁移后,报表读取者返回 AccessDenied。你将检查调用者、请求操作、资源和拒绝语句,每次修复一处不匹配,同时保留读取者有限的权限范围。
请先完成 为报表读取者授予最小权限,掌握策略字段和显式 Deny。这个全新 VM 准备了用于管理的 default 和用于作业的 reader。在 /home/labex/project 中操作,并在 AWS View 中比较存储策略与实际读取。
认证考点
| 认证 | 考点 | 本实验练习 |
|---|---|---|
| Solutions Architect – Associate (SAA-C03) | 任务 1.1 | 授权诊断与访问边界验证。 |
| Developer – Associate (DVA-C02) | 任务 2.1 | 授权诊断与访问边界验证。 |
| CloudOps Engineer – Associate (SOA-C03) | 任务 4.1 | 授权诊断与访问边界验证。 |
| Security – Specialty (SCS-C03) | 任务 4.2 | 基础练习:授权诊断与访问边界验证。 |
| Data Engineer – Associate (DEA-C01) | 任务 4.2 | 基础练习:授权诊断与访问边界验证。 |
实验概览

确认调用者并纠正请求操作
在本步骤中,你将区分身份错误与策略不匹配,再纠正 Allow 操作。使用不同凭据执行相同命令,可能产生不同授权结果。
迁移后的策略存在多个不匹配。修复一个字段后,请求仍可能被另一个字段或显式 Deny 拒绝。每次修改后,查看已保存的文档并重复同一个 reader 请求;仅凭 AccessDenied 响应未变,无法判断这一项修正是否正确。

cd /home/labex/project
aws sts get-caller-identity --query Arn --output text
aws sts get-caller-identity --profile reader --query Arn --output text
预期为 user/iam05-operator 和 user/report-reader。报表作业使用读取者,不使用操作员。以操作员身份确认对象存在,再以读取者身份重现作业失败。
aws s3api get-object \
--bucket labex-iam05-reports \
--key reports/today.txt operator-report.txt
cat operator-report.txt
aws s3api get-object --profile reader --bucket labex-iam05-reports --key reports/today.txt reader-before.txt || true
操作员获得 Daily orders: 145;读取者获得 AccessDenied。对象键缺失或连接错误需要不同调查。|| true 允许这个预期失败请求在粘贴序列中完成。
列出读取者策略,并读取存储文档。这些是操作员对作业身份的查询,不是让作业借用操作员访问权限。
aws iam list-user-policies --user-name report-reader
aws iam get-user-policy \
--user-name report-reader \
--policy-name LabReport \
--query PolicyDocument
Allow 指定 s3:ListBucket,而错误指定 GetObject。ListBucket 列出对象名称,并使用桶 ARN;它不下载对象字节。只将 Allow Action 改为 GetObject,保留当前 Resource 和 Deny,以便单独诊断下一处不匹配。
cat > repair-policy.json <<'JSON'
{"Version":"2012-10-17","Statement":[
{"Effect":"Allow","Action":"s3:GetObject","Resource":"arn:aws:s3:::labex-iam05-reports"},
{"Effect":"Deny","Action":"s3:GetObject","Resource":"arn:aws:s3:::labex-iam05-reports/reports/*"}
]}
JSON
aws iam put-user-policy \
--user-name report-reader \
--policy-name LabReport \
--policy-document file://repair-policy.json
aws iam get-user-policy \
--user-name report-reader \
--policy-name LabReport \
--query PolicyDocument
aws s3api get-object --profile reader --bucket labex-iam05-reports --key reports/today.txt reader-action-fix.txt || true
仍返回 AccessDenied。Action 现在正确,但纠正一个字段不保证所有适用检查均通过。
匹配完整对象 ARN
在本步骤中,你将修复 Resource,同时保留拒绝语句。GetObject 适用于包含对象键的对象 ARN。桶 ARN arn:aws:s3:::labex-iam05-reports 不匹配 arn:aws:s3:::labex-iam05-reports/reports/today.txt。
将 Allow Resource 替换为今天报表的准确对象 ARN。不要用 * 跨桶或对象键授权;作业只有一个所需输入。
cat > repair-policy.json <<'JSON'
{"Version":"2012-10-17","Statement":[
{"Effect":"Allow","Action":"s3:GetObject","Resource":"arn:aws:s3:::labex-iam05-reports/reports/today.txt"},
{"Effect":"Deny","Action":"s3:GetObject","Resource":"arn:aws:s3:::labex-iam05-reports/reports/*"}
]}
JSON
aws iam put-user-policy \
--user-name report-reader \
--policy-name LabReport \
--policy-document file://repair-policy.json
aws iam get-user-policy \
--user-name report-reader \
--policy-name LabReport \
--query PolicyDocument
aws s3api get-object --profile reader --bucket labex-iam05-reports --key reports/today.txt reader-resource-fix.txt || true
预期再次为 AccessDenied。现在 Allow 同时匹配 Action 和 Resource,因此应检查剩余语句。Deny 也匹配对 reports/* 的 GetObject,包括今天的报表。匹配的显式 Deny 优先于 Allow;将 Allow 移到文档后面也不能覆盖它。
修复 Deny 而不扩大访问
在本步骤中,你将纠正迁移后的 Deny 范围,并确认最小修复。预定保护针对私有数据,不应拒绝报表输入。保留准确读取 Allow,将 Deny 缩小到 private/*,而不是移除保护或增加更广泛授权。
cat > repair-policy.json <<'JSON'
{"Version":"2012-10-17","Statement":[
{"Effect":"Allow","Action":"s3:GetObject","Resource":"arn:aws:s3:::labex-iam05-reports/reports/today.txt"},
{"Effect":"Deny","Action":"s3:GetObject","Resource":"arn:aws:s3:::labex-iam05-reports/private/*"}
]}
JSON
aws iam put-user-policy \
--user-name report-reader \
--policy-name LabReport \
--policy-document file://repair-policy.json
aws s3api get-object \
--profile reader \
--bucket labex-iam05-reports \
--key reports/today.txt today.txt
cat today.txt
预期为 Daily orders: 145。以相同读取者身份测试邻近资源;完成的修复不得扩大权限范围。
aws s3api get-object --profile reader --bucket labex-iam05-reports --key reports/yesterday.txt yesterday-denied.txt || true
aws s3api get-object --profile reader --bucket labex-iam05-reports --key private/payroll.txt payroll-denied.txt || true
aws s3api get-object --profile reader --bucket labex-iam05-reference --key reference.txt reference-denied.txt || true
三个请求都必须返回 AccessDenied。所需读取授权也不能授权写入。尝试提供的替换文件,再验证原始报表字节未变。
aws s3api put-object --profile reader --bucket labex-iam05-reports --key reports/today.txt --body upload.txt || true
aws s3api get-object \
--profile reader \
--bucket labex-iam05-reports \
--key reports/today.txt today.txt
cat today.txt
aws iam get-user-policy \
--user-name report-reader \
--policy-name LabReport \
--query PolicyDocument
预期 PutObject 为 AccessDenied,报表仍为 Daily orders: 145。AWS View 现在显示今天报表为 Readable,其他资源为 Denied。策略查看解释修复;实际请求展示效果。

撤销修复并清理自己的数据
在本步骤中,你将移除 LabReport,并在报表仍存在时证明访问已撤回。再只删除练习报表桶及其三个对象键。
aws iam delete-user-policy --user-name report-reader --policy-name LabReport
aws iam list-user-policies --user-name report-reader
aws s3api get-object --profile reader --bucket labex-iam05-reports --key reports/today.txt revoked.txt || true
预期策略列表为空,读取返回 AccessDenied。策略撤销和数据删除是不同检查。保持参考桶不变。
aws s3api delete-object --bucket labex-iam05-reports --key reports/today.txt
aws s3api delete-object --bucket labex-iam05-reports --key reports/yesterday.txt
aws s3api delete-object --bucket labex-iam05-reports --key private/payroll.txt
aws s3api list-objects-v2 --bucket labex-iam05-reports
在成功的已认证响应中检查 KeyCount: 0,且 Contents 中没有剩余对象条目。
aws s3api delete-bucket --bucket labex-iam05-reports
aws s3api list-buckets --query 'Buckets[].Name'
aws s3api get-object --bucket labex-iam05-reference --key reference.txt reference.txt
cat reference.txt
只剩下参考桶,内容为 Platform reference: keep。服务失败不能证明删除。环境结束时,已准备好的身份会被回收;作业策略和练习数据已删除。
总结
你确认了调用者,将失败操作与 Allow Action 比较,匹配完整对象 ARN,并纠正重叠的显式 Deny。中间阶段的失败帮助识别剩余阻碍。最终读取者只能读取所需报表,不能写入或读取无关数据。你撤销修复后的授权,并完成限定范围的清理。诊断访问时,使用相同身份,并同时测试成功请求和禁止请求。
进一步阅读 AWS 官方资料:IAM 访问拒绝错误诊断.



