我的基于角色的访问控制是可行的解决方案吗?

2024-04-11

我正在我的 PHP 项目中设计一个非常简单的 RBAC(基于角色的访问控制)系统,经过一番思考后,我想出了一个解决方案,但是对构建业务系统了解不多,我不确定是否有或可能是我的解决方案的任何重大设计缺陷。

基本上,我想为用户提供一组“角色”。我将使用这些角色来允许或拒绝对应用程序上某些功能的访问。

这是角色表:

# Roles
    - id [auto-increment, unsigned]
    - role [string, length:50]

# User_Roles
    - user_id [FK:user_id, unsigned]
    - role_id [FK:roles_id, unsigned]

Note: user_id and role_id to be unique index

我担心的问题是数据库中没有关于该角色实际用途的信息。但后来我开始思考这是否重要。因为如果角色具有有意义的名称和结构,那么您可以查询user_roles表获取所有用户角色,然后在代码中类似:

# Fetch user with ID 1 from database
$user = User::find(1);

# Fetch the roles the user has from the database
# @returns : Array of roles
$userRoles = $user->roles()

# $userRoles = ['newmember', 'member.post', 'member.chat']

# Can the user send a message?
if(in_array('member.message', $userRoles)
{
    # User can send a message
}
else
{
    # User can not send a message
}

这些角色可以被管理,并且可以在组织内具有他们喜欢的任何意义。我只是担心数据库中的角色没有意义,我忍不住认为可能有更好的方法来实现这一点。

我的解决方案长期可行吗?

Thanks


这是我对此类 RBAC 系统的方法,首先我将应用程序拆分为模块,至少在逻辑上如此。

将模块视为应用程序中的实体/资源,可以对其执行某些操作。资源可以是用户、会员资格、产品……

假设我们正在构建一个像 Stackoverflow 这样的网站,并且有以下模块:

  • 问题(问答部分)
  • Chat

每个模块都在名为的应用程序数据库表中注册自己modules可能看起来像:

# Modules
  - id [an application-wide unique module identifier, provided by the module]
  - name [string, human readable]

每个模块都带有一组由模块预定义的操作,例如创建问题的操作、将用户从聊天室中踢出等。这些操作与模块一起安装到称为“操作”的应用程序数据库表中,它可能看起来像:

# Actions
  - module_id [reference to the modules table, is the namespace for the token]
  - action    [string / int, action identifier provided by the module, unique in the scope of the module]
  - name [string, human readable name]

  - Primary Key: [module_id, action]

现在让我们为 Stackoverflow 克隆定义模块和操作:

Modules
+------------------------------------------+
| ID        | Name                         |
+------------------------------------------+
| questions | Question and Answer Module   |
| chat      | Chat Module                  |
+------------------------------------------+

操作将与模块一起安装:

Actions
+-----------------------------------------------+
| Module    | Action    |  Name                 |
+-----------------------------------------------+
| questions | read      | Read Questions        |
| questions | create    | Create Questions      |
| questions | edit      | Edit Questions        |
| questions | delete    | Delete Questions      |
| questions | vote      | Vote on Questions     |
|           |           |                       |
| chat      | join      | Join the Chat         |
| chat      | kick      | Kick users            |
| chat      | create    | Create Chatrooms      |
+-----------------------------------------------+  

这里重要的是,您不能以系统管理员的身份直接修改这些表中的条目,因此没有 GUI 添加/删除操作等

下一步是为我们的系统创建一些角色,这是通过管理员的用户界面完成的,角色可以任意定义。

让我们从一些基本角色开始:

Q&A User:
   - can read questions
   - can create questions
Q&A Moderator:
   - can read questions
   - can create questions
   - can vote on questiosn
   - can edit questions
Q&A Admin:
   - can read questions
   - can create questions
   - can vote on questiosn
   - can edit questions
   - can delete questions

Chat User:
   - can join the chat

Chat Moderator:
   - can join the chat
   - can kick users from the chat

Chat Admin:
   - can join the chat
   - can kick users from the chat
   - can create chat rooms

首先,在角色表中创建角色:

# Roles
    - id [auto-increment, unsigned]
    - name [string, length:50]

填充我们的自定义定义:

Roles
+-----------------------+
| ID | Name             |
+-----------------------+
| 1  | Q&A User         |
| 2  | Q&A Moderator    |
| 3  | Q&A Admin        |
| 4  | Chat User        |
| 5  | Chat Moderator   |
| 6  | Chat Admin       |
+-----------------------+

在我们超级精美的管理用户界面中,我们现在有一个侧边栏,其中包含所有已安装模块及其相关操作的列表。自从 我们典型的管理员非常懒惰,对编程一无所知,他现在可以方便地为每个管理员分配操作 具有拖放功能的角色,即为角色分配权限。

这些分配的权限存储在我们的映射表中Roles_Actions:

# Roles_Actions
  - role_id
  - module_id 
  - action

  PK: [role_id, module_id, action]

填充的表:

Roles_Actions
+--------------------------------+
| Role ID | Module ID | Action   |
+--------------------------------+
|    1    | questions |  read    |
|    1    | questions |  create  |
|    2    | questions |  read    |
|    2    | questions |  create  |
|    2    | questions |  vote    |
|    2    | questions |  edit    |
               ...  
|    6    |    chat   |  join    |
|    6    |    chat   |  kick    |
|    6    |    chat   |  create  |
+--------------------------------+

现在我们必须将角色分配给系统中的用户,假设我们最初有四个用户:

- Chuck Norris which is a Q&A Admin and also a Chat Admin (UID = 1)
- Bruce Willis which is a Q&A Moderator and a Chat User   (UID = 2)
- Dilbert which is a Q&A Moderator and a Chat Moderator   (UID = 3)

# User_Roles
   - user_id [FK:user_id, unsigned]
   - role_id [FK:roles_id, unsigned]

填充的表:

Users_Roles
+---------------------------------+
| User ID | Role ID               |
+---------------------------------+
|    1    |  3 (= Q&A Admin)      |
|    1    |  6 (= Chat Admin)     |
|    2    |  2 (= Q&A Moderator)  |    
|    2    |  4 (= Chat User)      |
|    3    |  2 (= Q&A Moderator)  |  
|    3    |  5 (= Chat Moderator) | 
+---------------------------------+

因此,一个用户可以拥有多个角色,然后权限(模块/操作对)在应用程序层合并在一起。 如果您想更进一步,您还可以在角色模型中提供某种继承,例如问答主持人 可以定义为问答用户的子级,继承问答用户的所有权限并通过主持人权限扩展它。

那么应用层的授权是怎样的呢?

让我们假设 Dilbert(问答主持人和聊天主持人)登录系统,然后您收集他的所有角色和所有信息 分配给这些角色的权限。接下来开始构建权限树并删除所有重复的权限, 树可以表示为关联数组,例如:

呆伯特的权限树:

$dilberts_permissions = array(
   "questions" => array("read", "create", "vote", "edit")
   "chat"      => array("join", "kick")
)

为了方便起见,我们创建一个简单的辅助函数,例如:

function has_permission($path, $tree) {
   list($module, $action) = explode('.', $path);
   return (array_key_exists($module, $tree) && in_array($action, $tree[$module]));
}

在我们的代码中,我们现在可以检查是否允许 Dilbert 使用以下语法执行某些操作:

has_permission("questions.create", $dilberts_permissions);  // => TRUE
has_permission("questions.delete", $dilberts_permissions);  // => FALSE
has_permission("chat.join", $dilberts_permissions);         // => TRUE
has_permission("chat.create", $dilberts_permissions);       // => FALSE
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我的基于角色的访问控制是可行的解决方案吗? 的相关文章

随机推荐

  • Delphi 2009 功能区控件 - 玻璃框架

    我已经开始使用 Delphi 2009 中新的内置功能区控件并使用自定义框架 以便应用程序按钮和迷你工具栏向上滑动到窗口框架上 但我想知道在 Vista 上是否应该使用玻璃效果 例如Office 2007 可以 如果可以 我将如何启用此设置
  • JSF 加密劫持恶意软件

    现在我知道这不是一个安全或恶意软件删除网站 不过我觉得这是一个 JSF 特定问题 我注意到我的网站不断受到向网页注入 JavaScript 文件的攻击 该恶意软件正在从某个具有以下模式的随机 URL 加载脚本文件 https johndi3
  • 针对性能或代码大小的 C 编码实践 - 超出编译器的范围

    我想看看程序员可以用 C 做什么 这可以确定生成的目标文件的性能和 或大小 For e g 1 将简单的 get set 函数声明为内联函数可以提高性能 但代价是占用空间更大 2 对于不使用循环变量本身值的循环 向下计数到零 而不是向上计数
  • 比较 python 中的两个列表并返回匹配值的索引

    对于两个列表 a 和 b 如何获取两者中出现的值的索引 例如 a 1 2 3 4 5 b 9 7 6 5 1 0 return indices of a a b 会回来 0 4 with a 0 a 4 1 5 做到这一点的最好方法是b a
  • 如何将复杂的 django 查询构建为字符串

    我正在动态生成具有多个参数的查询字符串 我试图在字符串中包含对象名称 坚果 果酱 该查询必须是 OR 查询 我的代码如下 我收到如下所示的错误 解决方案here https stackoverflow com questions 18161
  • 覆盖 Hibernate 注解

    我正在开发一个使用 Hibernate 并连接到 Oracle 实例的 Java 应用程序 另一个客户希望使用相同的应用程序 但要求它在 MS SQL Server 上运行 我想避免对现有注释进行更改 而是创建一个 xml 文件包 我们可以
  • 如何从 SharePoint 自定义列表中的日期/时间列获取日期和当前时间

    我在 sharepoint 2007 的自定义列表之一中有一个名为 提交日期 的列作为日期 时间 它总是设置为今天的日期和上午 12 点时间 而不是我想显示今天的日期和当前时间 hh mm ss 我尝试创建计算列 TestDate 公式为
  • 如何从给定缓冲区解码视频? (媒体编解码器)

    我需要解码来自交错流 如 AVI 的数据 所以 这意味着我有一个以这种形状 序列 构建的容器 mp4 gt other data gt mp4 gt other data gt so on 目前我有一个基本的实现MediaCodec解码器
  • 为什么直接导航到该路线时不匹配?

    郑重声明 这是使用当前相当新的 angular router 3 0 0 alpha 8 路线定义位于帖子底部 当尝试在我的应用程序中导航时 行为会有所不同 具体取决于我是直接输入 URL 还是通过链接输入 Works 进入http loc
  • 一个人可以采用敏捷技术吗? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 目前正在找工作 我看到很多地方都要求敏捷经验 但在我找到使用敏捷的团队的工作之前 我怀疑我永远不会获得这种经验 是否可以仅由一个人采用敏捷方法
  • AttributeError:模块“numpy”没有属性“core”

    我想知道是否有人在运行 Spark 并尝试导入 numpy 时遇到这个问题 Numpy 在标准笔记本中正确导入 但是当我尝试通过运行 Spark 的笔记本导入它时 出现此错误 我有最新版本的 numpy 并且正在运行最新的 anaconda
  • RxJava 中的笛卡尔积

    是否有可能在rxjava中获得两个Observables的笛卡尔积 像这样的事情 A gt 1 2 3 B gt a b A x B gt 1 a 1 b 2 a 2 b 3 a 3 b 你想要的是 对于一个数字 产生与你有字母一样的一对
  • 提交 OSX 应用程序及其捆绑包中的帮助程序应用程序

    我真的要被这个问题搞疯了 我有一个应用程序 其中包含一个简单的帮助程序应用程序 用于管理主应用程序的登录项 当我尝试提交应用程序时 我收到与配置文件和权利相关的错误 我确信问题与助手应用程序有关 因为在我添加它之前 提交工作没有问题 目前
  • PHP获取下拉列表选择选项值

    在我的下拉列表中 每个选项都有两个不同的值 我怎样才能检索两者 让我来说明一下我的意思
  • 从 Html 源在 Excel 中创建注释

    因此 可以从 Html 创建 Excel 文件 我发现很多事情都是可能的 比如添加图像 格式化等 只需一些 css 调整 然而 我现在想做的是让小红色三角形评论显示出来 我创建了一个空白的 Excel 文件 除了注释之外什么都没有 但它生成
  • 在 python 中向量化 for 循环

    我是 python 的新手 有一个关于向量化代码的问题要问 def makeNames2 nList for nLi in nList nLIdx i for i j in enumerate nList if j nLi if nLIdx
  • 如何将 MapView 从像素缩放到米

    我正在制作一个使用 Google Maps API 的 Android 应用程序 我想将 MapView 缩放到 X pixels X meters 例如 我的屏幕中 MapView 的 5 像素 实际距离为 20 米 那可能吗 Thx 使
  • React table v7固定列与react-window

    我有一张带有react table v7 的表 使用react window进行虚拟化 现在表的最后一列已修复 但我无法修复表的最后一列 React window 的内部元素有overflow auto这不会让色谱柱最终变得粘稠 这是lin
  • VisualStateManager WPF 不工作

    我专门在 VS Blend 2017 设计器中设计了一个窗口 没有对 XAML 代码进行任何更改 我创建了一个 StateGroup 和一个 State 并记录了 Button 上的更改 当尝试从代码隐藏应用状态时 没有任何反应 我也看过同
  • 我的基于角色的访问控制是可行的解决方案吗?

    我正在我的 PHP 项目中设计一个非常简单的 RBAC 基于角色的访问控制 系统 经过一番思考后 我想出了一个解决方案 但是对构建业务系统了解不多 我不确定是否有或可能是我的解决方案的任何重大设计缺陷 基本上 我想为用户提供一组 角色 我将