「容器管理系统」开发篇:5. 如何实现 RBAC 权限管理(一)

1,582 阅读5分钟

回顾

项目已开源:基于 Golang 的 容器管理系统

什么是 RBAC ?

RBAC模型(Role-Based Access Control:基于角色的访问控制)是20世纪90年代研究出来的一种新模型,但在20世纪70年代的多用户计算时期,这种思想就被提出来了,直到20世纪90年代中后期,RBAC才在研究团队中得到一些重视,并先后提出了很多类型的RBAC模型。其中以美国George Mason大学信息安全实验(LIST)提出的RBAC96模型最具有代表,并得到普遍的公认。

RBAC认为权限授权的过程可以抽象的概括为:Who是否可以对What进行How的访问操作,并对这个逻辑表达式进行判断是否为True的求解过程,也就是将权限问题转换为WhatHow 的问题,WhoWhatHow构成了访问权限三元组

什么是访问控制 ?

访问控制是指在计算机系统中,对于资源访问进行控制的一种安全措施。主要的访问控制类型有三种模式:自主访问控制(DAC)、强制访问控制(MAC)和基于角色访问控制(RBAC)。其中,自主访问控制是指资源的所有者可以自由地控制资源的访问权限;强制访问控制是指系统管理员通过设定安全级别和访问规则来控制资源的访问权限;基于角色访问控制是指根据用户的角色来控制其对资源的访问权限。在实际应用中,访问控制可以应用于文件读写访问控制、进程访问控制、内存访问控制以及数据库/数据访问控制等方面。

RBAC的组成有哪些 ?

RBAC模型里面,有个基础组成部分,分别是用户角色权限

RBAC通过定义角色的权限,并对用户授予某个角色从而来控制用户的权限,实现用户和权限的逻辑分离(区别于ACL模型),极大方便了权限的管理。

RBAC模型中的一些名词:

  • User(用户):每个用户都有唯一的UID识别,并被授予不同的角色;
  • Role(角色):不同角色具有不同权限;
  • Permission(权限):访问权限;
  • 用户-角色映射:用户和角色之间的映射关系;
  • 角色-权限映射:角色和权限之间的映射关系。

它们之间的关系:

RBAC模型

RBAC 如何设计?

这里采用标准RBAC模型来设计角色继承的RBAC的权限模型。这里不赘述其他设计模型,请自行了解!

标准RBAC模型的表是比较简单了,要表示用户-角色-权限三者之间的关系,首先要创建用户表、角色表、权限表,用户和角色是多对多的关系,角色和权限是多对多的关系,需要再创建两张关系表,分别是用户-角色关系表和角色-权限关系表。这六张表的ER图如下所示:

标准RBAC模型数据表ER图

定义 RBAC 数据表

cloud_user 用户表

type CloudUser struct {
    common.Model
    UserName  string `json:"user_name" gorm:"size:200;not null;uniqueIndex;default:'';comment:用户名"`
    PassWord  string `json:"pass_word" gorm:"size:255;not null;default:'';comment:密码"`
    UserEmail string `json:"user_email" gorm:"size:200;not null;default:'';comment:邮箱"`
    LoginIp   string `json:"login_ip" gorm:"size:200;not null;default:'';comment:登录IP"`
    LastTime  uint32 `json:"last_time" gorm:"index;not null;default:0;comment:最后登录时间"`
    Status    uint8  `json:"status" gorm:"index;not null;default:0;comment:用户状态: 0正常、1禁用"`
    Admin     uint8  `json:"admin" gorm:"index;not null;default:0;comment:是否超级管理员:0否、1是"`
    common.ModelTime
}

func (c CloudUser) TableName() string {
    return "cloud_user"
}

cloud_role 角色表

type CloudRole struct {
    RoleId     uint32 `json:"role_id" gorm:"primaryKey;autoIncrement;comment:唯一编号"`
    RoleName   string `json:"role_name" gorm:"size:200;not null;index;default:'';comment:角色名"`
    RoleKey    string `json:"role_key" gorm:"size:128;not null;uniqueIndex;default:'';comment:角色Key"`
    RoleRemark string `json:"role_remark" gorm:"size:255;not null;default:'';comment:角色备注"`
    RoleSort   uint8  `json:"role_sort" gorm:"not null;index;default:0;comment:角色排序"`
    Status     uint8  `json:"status" gorm:"not null;index;default:0;comment:角色状态: 0正常、1禁用"`
    common.ControlBy
    common.ModelTime
}

func (c CloudRole) TableName() string {
    return "cloud_role"
}

cloud_menu 菜单表

type CloudMenu struct {
    MenuId     uint32 `json:"menu_id" gorm:"primaryKey;autoIncrement;comment:唯一编号"`
    MenuName   string `json:"menu_name" gorm:"size:200;not null;default:'';comment:菜单名"`
    MenuTitle  string `json:"menu_title" gorm:"size:128;not null;default:'';comment:菜单标题"`
    MenuIcon   string `json:"menu_icon" gorm:"size:128;not null;default:'';comment:菜单图标"`
    MenuPath   string `json:"menu_path" gorm:"size:255;not null;uniqueIndex;default:'';comment:菜单路径"`
    PathGroup  string `json:"path_group" gorm:"size:255;not null;default:'';comment:菜单路径组"`
    MenuType   string `json:"menu_type" gorm:"size:255;not null;default:'';comment:菜单类型"`
    MenuMethod string `json:"menu_method" gorm:"size:16;not null;default:'';comment:菜单请求类型"`
    Permission string `json:"permission" gorm:"size:255;not null;uniqueIndex;default:'';comment:菜单权限标识"`
    ParentId   uint32 `json:"parent_id" gorm:"index;not null;default:0;comment:父级ID"`
    Component  string `json:"component" gorm:"size:255;not null;uniqueIndex;default:'';comment:菜单组件"`
    MenuSort   uint8  `json:"menu_sort" gorm:"index;not null;default:0;comment:菜单排序"`
    Visible    uint8  `json:"visible" gorm:"index;not null;default:0;comment:菜单是否显示:0显示、1隐藏"`
    IsFrame    uint8  `json:"is_frame" gorm:"index;not null;default:0"`
    common.ControlBy
    common.ModelTime
}

func (c CloudMenu) TableName() string {
    return "cloud_menu"
}

cloud_user_role 用户-角色关联表

type CloudUserRole struct {
    UID    uint32 `json:"uid" gorm:"primaryKey;autoIncrement;comment:用户ID"`
    RoleId uint32 `json:"role_id" gorm:"not null;index;default:0;comment:角色ID"`
    common.ControlBy
    common.ModelTime
}

func (c CloudUserRole) TableName() string {
    return "cloud_user_role"
}

cloud_role_menu 角色-菜单关联表

type CloudRoleMenu struct {
    RoleId uint32 `json:"role_id" gorm:"not null;index;default:0;comment:角色ID"`
    MenuId uint32 `json:"menu_id" gorm:"not null;index;default:0;comment:菜单ID"`
    common.ControlBy
    common.ModelTime
}

func (c CloudRoleMenu) TableName() string {
    return "cloud_role_menu"
}

结束语

  • 什么是RBAC
  • RBAC 的组成
  • RBAC 之间的关系
  • RBAC 的设计模型
  • 定义 RBAC 数据表

下节预告:如何实现 RBAC 权限管理(二) 主要内容:

  • 如何实现 RBAC
  • 权限二叉树的设计与实现