Friparia Blog

Do more

信息系统中的权限控制(二):基于层级的权限控制

| Comments

上文中我们讲了一种最简单地权限控制方法——基于业务逻辑,也就是具体问题具体分析的一种方法。这篇文章主要介绍基于层级和基于角色的权限控制方法。

基于层级的权限控制

打个比方,当我们的系统中有超级管理员,普通管理员,普通用户,游客这些角色的时候,我们不能再使用业务逻辑来判断了,不然可能会产生大量重复无用代码。而我们会发现,这几种角色是存在着明显的层级关系,游客的可以进行的操作最少,超级管理员可以进行的操作最多,这时候我们就可以预定义他们的等级,然后再在具体的业务模块进行判定。

config.php
1
2
3
4
5
6
<?php
define("SUPERADMIN", 4);
define("ADMIN", 3);
define("USER", 2);
define("GUEST", 1);
?>

然后在每个页面或者操作之前,进行一次权限检查,只需要调用一次permissionCheck()函数,就检验当前的用户是不是具有用户以上的等级的权限,如果没有的话就会跳转到未授权页面。

SomePage.php
1
2
3
4
<?php
permissionCheck(USER);
//do something
?>

这样设计的好处就是大大的简化了权限检查,以较少的代码来完成这样一件事情,就我所知,使用这用方法的项目主要是nexusphp,是各个bt、pt站的一个解决方案。

简单是简单,但是这样操作缺乏灵活性和扩展性,比如我们要求,用户可以访问到的页面管理员不能访问得到(部分用户的隐私信息等),基于层级的权限控制就没有办法来完成这样的需求了。而且这种情况不太适合当前所流行的MVC的架构,这时候我们就需要引入基于角色的权限访问控制。

基于角色的权限控制

基于角色的访问控制的基本思想是将访问的权限分给不同的用户,访问控制基于角色的不同来进行控制,例如,一个学生信息管理系统,有学生、教师、教工等角色。这些角色的权限各不相同,我们实质上是维护一个访问控制表(ACL:Access Control List)来进行权限判定的。这张访问控制表在MVC架构下非常容易实现和使用,因为我们的具体的操作其实就是一个controller下的action,以角色为一个维度,操作为一个维度,便可以建立一张访问控制表,如下所示

permission/role 学生 教师 辅导员
check score yes yes yes
change score no yes no
change dorm no no no
change class no yes yes

不同的角色拥有不同的权限,这张表的维护我们可以将其放在数据库或者其他什么地方,而我们在具体实现的时候可以通过以下方式调用来检查权限:

SomeController.php
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
class SomeController{

    public function __construct(){
        checkPermission($controller, $action);
    }

    public function action1(){
    }

    //other codes
}
?>

我们还是可以将其封装成基类让我们的具体实现Controller继承从而复用我们的代码。

这样当我们有一个辅导员要改成绩的需求的话,只需要在数据库里将辅导员的change score权限改为yes即可。基于角色的权限管理方式具有灵活性、方便性和安全性的特点,而且现在使用的也非常广泛。但是基于角色的权限管理中,角色与客体并无直接的联系,即没有办法进行横向权限的判定,从而会存在一些越权的BUG,比如数学老师能够修改语文成绩这样的问题,我们将会在下一篇中提出一种基于资源的权限控制方式,以这种方式来做横向权限的判定。

Comments

Recent Posts

GitHub Repos

  • Status updating...