You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何搭建类AWS IAM的权限模型?求通用实现方案及细节

参照IAM模型自研权限系统的通用实现指南

我之前在自研企业系统时,也遇到过和你一样的问题——搜IAM相关内容全是AWS官方教程,找不到通用落地的技术细节。结合实际落地经验,给你梳理下通用术语、数据库设计和核心实现要点:

一、通用权限模型术语(对应AWS IAM概念)

先把AWS的概念映射到通用场景,避免被云服务绑定:

  • Principals(主体):通用叫「权限主体」,指能发起操作的实体,包括:
    • 终端用户(User)
    • 角色(Role):可被多个主体继承的权限集合(比如「管理员」「编辑者」)
    • 服务账号(Service Account):系统内部服务/脚本发起请求的身份
  • Resources(资源):通用叫「受保护资源」,是系统中需要控制访问的对象,比如订单、文档、API接口、菜单等
  • Actions(操作):通用叫「资源操作」,是主体对资源能执行的具体动作,比如「创建订单」「读取文档」「删除用户」
  • Policy(权限策略):定义「主体-资源-操作」关系的规则集合,核心是**允许(Allow)/拒绝(Deny)**的判断逻辑
  • Assignment(权限绑定):将策略/角色关联到主体的关系(比如把「编辑者」角色绑定给用户张三)

二、具体实现细节

1. 数据库结构设计

推荐用关系型数据库(MySQL/PostgreSQL)实现,核心表结构如下:

(1)主体表 principals

CREATE TABLE principals (
    id INT PRIMARY KEY AUTO_INCREMENT,
    type ENUM('user', 'role', 'service') NOT NULL, -- 区分主体类型
    identifier VARCHAR(100) UNIQUE NOT NULL, -- 用户ID/角色名称/服务账号ID
    name VARCHAR(100) NOT NULL, -- 显示名称
    description TEXT,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

(2)资源表 resources

支持层级资源(比如文件夹下的文档):

CREATE TABLE resources (
    id INT PRIMARY KEY AUTO_INCREMENT,
    resource_type VARCHAR(50) NOT NULL, -- 资源类型:order/document/menu
    resource_id VARCHAR(100) UNIQUE NOT NULL, -- 资源唯一标识(比如订单ID)
    parent_resource_id INT NULL, -- 父资源ID(用于层级结构)
    owner_principal_id INT NULL, -- 资源所属主体ID
    attributes JSON, -- 资源扩展属性(比如订单状态、文档大小)
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (parent_resource_id) REFERENCES resources(id),
    FOREIGN KEY (owner_principal_id) REFERENCES principals(id)
);

(3)操作表 actions

统一管理所有允许的操作,避免硬编码:

CREATE TABLE actions (
    id INT PRIMARY KEY AUTO_INCREMENT,
    action_key VARCHAR(100) UNIQUE NOT NULL, -- 操作标识:比如 'order:create' 'document:read'
    resource_type VARCHAR(50) NOT NULL, -- 关联资源类型
    name VARCHAR(100) NOT NULL, -- 操作名称:「创建订单」「读取文档」
    description TEXT,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

(4)策略表 policies 和策略语句表 policy_statements

策略是多个权限规则的集合,用拆分表避免冗余:

CREATE TABLE policies (
    id INT PRIMARY KEY AUTO_INCREMENT,
    policy_name VARCHAR(100) UNIQUE NOT NULL,
    description TEXT,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE policy_statements (
    id INT PRIMARY KEY AUTO_INCREMENT,
    policy_id INT NOT NULL,
    effect ENUM('Allow', 'Deny') NOT NULL, -- 优先Deny(和IAM一致)
    principal_id INT NULL, -- 关联主体ID,NULL表示所有主体
    resource_condition VARCHAR(200), -- 资源匹配条件:比如 'resource_type = "order" AND owner_principal_id = ${principal_id}'
    action_ids TEXT, -- 关联操作ID,用逗号分隔(或用中间表多对多)
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (policy_id) REFERENCES policies(id),
    FOREIGN KEY (principal_id) REFERENCES principals(id)
);

(5)角色绑定表 role_assignments

实现主体继承角色权限:

CREATE TABLE role_assignments (
    id INT PRIMARY KEY AUTO_INCREMENT,
    principal_id INT NOT NULL, -- 被绑定的主体(比如用户)
    role_id INT NOT NULL, -- 绑定的角色(来自principals表,type='role')
    effective_start DATETIME DEFAULT CURRENT_TIMESTAMP,
    effective_end DATETIME NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (principal_id) REFERENCES principals(id),
    FOREIGN KEY (role_id) REFERENCES principals(id),
    UNIQUE KEY (principal_id, role_id)
);

2. Actions的存储与管理

两种主流方案,根据系统复杂度选择:

  • 枚举式存储(推荐):就是上面的actions表,所有操作提前定义好,优点是:
    • 便于权限审计和管理(能清晰看到所有可授权操作)
    • 避免非法操作请求(只有表中存在的action才允许判断)
    • 命名规范统一:建议用「资源类型:操作名称」格式,比如order:createdocument:update,和IAM的命名逻辑对齐但更通用
  • 动态匹配式存储:适合操作灵活、频繁新增的系统,允许用通配符(比如order:*表示所有订单操作),可以把action直接存在策略语句中,不用单独建表,但要注意:
    • 需实现通配符匹配逻辑(比如用正则表达式)
    • 要做权限缓存,避免每次请求都做字符串匹配影响性能

3. 权限判断核心逻辑

和IAM的判断逻辑一致,步骤如下:

  1. 收集主体的所有有效策略:包括直接绑定到主体的策略,以及主体继承的角色所关联的策略
  2. 匹配请求的资源和操作
    • 提取请求中的principal_idresource_type/resource_idaction_key
    • 遍历所有策略语句,筛选出匹配当前主体、资源、操作的语句
  3. 优先判断Deny:如果存在任何一条effect=Deny的匹配语句,直接拒绝请求
  4. 判断Allow:如果存在至少一条effect=Allow的匹配语句,允许请求;否则拒绝

补充条件判断:比如要实现「用户只能操作自己的订单」,可以在resource_condition中写owner_principal_id = ${principal_id},判断时把${principal_id}替换为当前主体的ID,执行条件校验。

三、实践建议

  • 权限缓存:把主体的权限集合(比如允许的action_key和资源范围)缓存到Redis中,减少数据库查询次数,提升判断性能
  • 最小权限原则:给主体分配刚好够用的权限,避免过度授权
  • 审计日志:记录所有权限判断请求(主体、资源、操作、结果),便于排查权限问题和合规审计
  • 权限测试:在系统上线前,针对不同角色/用户进行权限测试,确保逻辑符合预期

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

火山引擎 最新活动