You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取AWS Policy类型定义?用Go结构体解析JSON策略

这确实是个实用的需求——用强类型结构体解析AWS IAM Policy,比用interface{}方便太多了!下面我一步步给你讲清楚怎么实现:

定义匹配AWS Policy的Go结构体

首先得贴合AWS IAM Policy的JSON结构来定义结构体,重点要处理Action字段的特殊情况:它既可以是单个字符串(比如s3:ListBucket),也可以是字符串数组。我们需要自定义类型来兼容这两种格式,同时处理嵌套的Condition结构。

import (
    "encoding/json"
    "fmt"
    "strings"
)

// 自定义Action类型,兼容单个字符串或字符串数组的JSON格式
type Action []string

// 实现UnmarshalJSON方法,自动处理两种格式的转换
func (a *Action) UnmarshalJSON(data []byte) error {
    // 先尝试解析为单个字符串
    var singleAction string
    if err := json.Unmarshal(data, &singleAction); err == nil {
        *a = []string{singleAction}
        return nil
    }
    // 若失败,再尝试解析为字符串数组
    var multiActions []string
    if err := json.Unmarshal(data, &multiActions); err != nil {
        return err
    }
    *a = multiActions
    return nil
}

// Statement 对应Policy中的单个权限声明对象
type Statement struct {
    Sid       string                 `json:"Sid,omitempty"` // omitempty表示空值时序列化会忽略该字段
    Effect    string                 `json:"Effect"`
    Action    Action                 `json:"Action"`
    Resource  string                 `json:"Resource"`
    Condition map[string]interface{} `json:"Condition,omitempty"` // 用通用map适配灵活的Condition结构
}

// Policy 顶层的IAM Policy结构体
type Policy struct {
    Version   string      `json:"Version"`
    Statement []Statement `json:"Statement"`
}
反序列化并直接访问字段

有了上面的结构体,你就可以直接把JSON字符串反序列化为Policy类型,然后像访问普通结构体字段一样操作它:

func main() {
    firstKey := `{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": "s3:ListBucket", "Resource": "arn:aws:s3:::amit", "Condition": { "StringLike": { "s3:prefix": "Development/*" } } }, { "Sid": "VisualEditor1", "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject" ], "Resource": "arn:aws:s3:::amit/Development/*" } ] }`

    var policy Policy
    err := json.Unmarshal([]byte(firstKey), &policy)
    if err != nil {
        fmt.Printf("反序列化失败: %v\n", err)
        return
    }

    // 直接访问Version字段
    fmt.Println("Policy版本:", policy.Version)

    // 遍历所有Statement并输出字段
    for idx, stmt := range policy.Statement {
        fmt.Printf("\n第%d条权限声明:\n", idx+1)
        fmt.Println("生效规则:", stmt.Effect)
        fmt.Println("操作权限:", strings.Join(stmt.Action, ", "))
        fmt.Println("资源ARN:", stmt.Resource)
        if stmt.Condition != nil {
            fmt.Println("附加条件:", stmt.Condition)
        }
    }
}
关键细节说明
  • 自定义Action类型:通过实现UnmarshalJSON方法,我们把两种格式的Action统一转换成[]string,后续访问时不用再区分单个值还是数组,简化了逻辑。
  • 结构体标签:json:"Version"这类标签是告诉Go的JSON解析器,结构体字段对应JSON中的哪个键名;omitempty标签则是优化序列化行为(反序列化时不影响)。
  • Condition字段:用map[string]interface{}是因为AWS Policy的Condition结构非常灵活,不同的条件操作符(比如StringLike、NumericEquals)对应不同的嵌套结构。如果你的场景有固定的Condition格式,也可以定义更具体的结构体来替代通用map。

内容的提问来源于stack exchange,提问作者Amit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:51:58