Php 基于角色的访问有什么变化?

Php 基于角色的访问有什么变化?,php,web-services,security,Php,Web Services,Security,我有一个web应用程序,具有非常简单的基于角色的访问控制。当前设置有三个角色: -超级管理员 -管理员 -用户 每个页面请求根据该页面的最低访问级别检查用户角色,并根据比较结果授予(或拒绝)对该页面的访问 管理员和用户之间也存在一对多的关系;每个管理员负责一个或多个用户 我现在面临的挑战是添加另一个角色(受限管理员),并根据负责每个用户的管理员是否具有ADMIN或LIMITED ADMIN角色来限制每个用户的访问权限 对于这种情况,是否有既定的最佳实践?修改我当前的访问逻辑来处理这个场景是非常简

我有一个web应用程序,具有非常简单的基于角色的访问控制。当前设置有三个角色:

-超级管理员
-管理员
-用户

每个页面请求根据该页面的最低访问级别检查用户角色,并根据比较结果授予(或拒绝)对该页面的访问

管理员和用户之间也存在一对多的关系;每个管理员负责一个或多个用户

我现在面临的挑战是添加另一个角色(受限管理员),并根据负责每个用户的管理员是否具有ADMIN或LIMITED ADMIN角色来限制每个用户的访问权限


对于这种情况,是否有既定的最佳实践?修改我当前的访问逻辑来处理这个场景是非常简单的,但是随着应用程序的增长,我开始怀疑我是否应该转向更健壮的访问控制模型。首先想到的是访问控制列表,但它们似乎无法处理一个用户的访问可能受到另一个用户的角色限制的情况。

您提出了错误的问题,而不是问“用户是什么角色”,您应该问“当前用户可以做x吗?”。这将意大利面代码变成一种非常灵活的基于角色的访问控制

错误代码:

  if ($user === 'Admin' || $user === 'Super Admin' || $user === 'SubAdmin'){
     // spaghetti
  }
好代码:

$resources = array(
   'edit_page',
   'view_page',
   'delete_page',
);

$roles = array(
    'admin' => array(
         'edit_page',
         'view_page',       
    ),
    'superadmin' => array(
         'edit_page',
         'view_page', 
         'delete_page',
    ),
    'user' => array(
         'view_page'
    ),
);

function can_do($x){
    $user_role;  // (currently logged in user role)
    return in_array($x, $roles[$user_role]);
}
有一个微妙但非常重要的区别。现在我们可以问,“当前用户能做x吗?”


现在,我们只需要询问我们是否可以做一些事情添加一个新角色(superduperadmin)很简单,您只需要在一个地方进行更改。

要明确。而不是每次访问资源时都要检查用户的关联管理员,一种更简单、更易于维护的方法是将其作为一个独特的用户角色来实现。例如,当用户由受限管理员创建时,他们的角色可能是受限用户

(当然,访问控制列表也可以达到同样的效果。同样的原则也适用——为用户分配明确的角色,而不是基于负责用户的管理员的隐式访问级别)


这样做的后果是,当管理员的管理被更改、管理员帐户被禁用等时,您还需要明确地说明用户的角色发生了什么,但是我认为,即使使用原始的隐式方法,您仍然必须考虑这些情况。您忽略的任何边界情况都更有可能导致安全漏洞,而显式角色本质上更安全。

这里有两个问题

  • 您不是在“添加新角色”。您正在添加两个。管理员创建的用户和有限管理员创建的用户必须具有不同的权限集,这意味着这实际上是两个不同的角色。这样编码。基于继承将一个物理角色映射到两个逻辑角色的想法不必要地使事情复杂化
  • 您正在将安全模型更改为更细粒度。您的代码以前有三个角色,现在有五个(不管第五个角色是否得到官方认可)
  • 访问控制列表提供了代码和给定角色之间的间接级别。与检查用户角色不同,您只需验证所请求的操作-创建?阅读更新?删除?是或否,简单的决定。代码永远不会改变。相反,在创建ACL时,分配角色的UI会打包权限集。在“用户创建”屏幕中,管理员看到的权限由管理员限制、常规或超级权限的级别定义。但是一旦ACL被设置,它是由管理员还是有限管理员设置的问题就无关紧要了。在运行时,它只是简单地创建?阅读更新?删除?是或否,简单的决定

    完成此操作后,添加新角色就像打包ACL上的权限集合一样简单。添加新特权很容易,只需扩展ACL即可。这些更改都不会影响以前的代码解释ACL的方式


    记住,特权是控制对真实资源的访问的有形的东西。角色是由权限集合表示的抽象概念。一旦这两件事在代码中分开,像您描述的那样的更改就会容易得多。两人会面的唯一地方是在UI中创建用户并分配权限。

    虽然我的代码没有“坏代码”示例那么糟糕,但我同意;访问控制列表比我现在做的要灵活得多。然而,我的新要求要求我根据相关管理员的角色确定“用户”访问权限。并不是每个用户都与同一个管理员关联,并且有几个不同的“管理员”角色。我认为这正是我需要做的。谢谢你把它拆开,现在清楚多了。谢谢托德。这与T.Rob所说的相似。非常有用。
    if (can_do('view_page'))
    {
       // clean code
    }