权限控制

#1 jake

本章介绍SpeedPHP的权限控制——spAcl扩展的使用方法。

spAcl是通过读取角色权限列表,在路由前扩展点位置,判断当前角色是否可以访问当前页面程序,执行放行或拒绝转向。这里Acl可以总结成三部分:


  • 拥有一张角色权限表数据,记录各页面的权限和对应的角色。
  • 通过框架扩展点执行,保证未执行用户级代码前进行权限判断,保证安全;同时免除用户级代码参杂权限控制器代码,让代码更清晰、可控。
  • 判断角色是否拥有权限时,可使用spAcl的“强制控制”或“有限控制”,分别适用不同的权限控制需要。

“强制控制”是最大程度控制,也就是“只有——有权限的角色——才可以访问”,比如大部分的后台程序或者企业内部办公系统,除了登录页面外,其他的功能都要登录验证身份后才能使用。

“有限控制”是仅限于列表中的页面才需要验证权限,也就是“除非——有权限要求的页面——才需要验证”。例如简单如留言本,任何人都是可以留言的,但是如果是删除留言的操作,那么仅能由留言本的主人才能执行了。

代码下载:201103300722135585[1].zip


“有限控制”

有限控制是比较简单的权限控制模式,也就是当某个页面被权限表声明为“需要某权限才能进入”,那么这个页面才会被保护起来。


201103300715118203[1].jpg

使用方式

1. 入口文件设置扩展点

'launch' => array( 
         'router_prefilter' => array(
                array('spAcl','mincheck') // 开启有限的权限控制
         )
),
2. 建立权限记录表——acl表,如果程序设置了表前缀,请建立“表前缀+acl”为名称的权限表(如pubgb_acl)
CREATE TABLE acl
(
        aclid int NOT NULL AUTO_INCREMENT,
        name VARCHAR(200) NOT NULL,
        controller VARCHAR(50) NOT NULL,
        action VARCHAR(50) NOT NULL,
        acl_name VARCHAR(50) NOT NULL,
        PRIMARY KEY (aclid)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci
3. 在“有限控制”的情况下,在权限表中的每一条记录,都代表了一个“限制”——相对来说,没有记录就没有“限制”。
INSERT INTO `pubgb_acl` VALUES ('1', '留言管理后台', 'admin', 'index', 'GBADMIN');
INSERT INTO `pubgb_acl` VALUES ('2', '删除留言', 'admin', 'del', 'GBADMIN');
INSERT INTO `pubgb_acl` VALUES ('3', '提交留言', 'main', 'post', 'GBUSER');
INSERT INTO `pubgb_acl` VALUES ('4', '提交留言', 'main', 'post', 'GBADMIN');

  • 任意访问者:其他全部控制器/动作页面
  • GBUSER:其他全部控制器/动作页面,main/post
  • GBADMIN:其他全部控制器/动作页面,main/post,admin/index,admin/del

比如这里设置了 admin/index 页面只能由角色“GBADMIN”进入,那么,在当前访问者没有赋予角色“GBADMIN”,那么访问者在访问admin/index的时候,将会收到警告信息并返回首页。

4. 怎么为当前访问者赋予角色呢?很简单,通过spClass('spAcl')->set("GBADMIN");进行赋值即可。如:

class main extends spController
{
        function index(){
                if( 'jake' == $this->spArgs('inputname') && '123456' == $this->spArgs('inputpass') ){
                        spClass('spAcl')->set("GBADMIN"); // 对当前访问者(SESSION)赋予THEADMIN角色
                        $this->jump(spUrl('admin', 'index')); // 跳转到admin/index
                }
                header("Content-type: text/html; charset=utf-8");
                echo '
用户:
密码:

';
        }
}
?>

这里的表单直接提交,判断用户名和密码正确后,对当前访问者赋予了GBADMIN角色,然后就可以跳转到admin/index页面上执行了。

当浏览器关闭,或者执行spClass('spAcl')->set("");的时候,将取消当前访问者的角色,也就是退出登录了。

“有限控制”的流程图如下:


201103300718158722[1].jpg

“强制控制”

强制控制是比较严格的权限控制模式,默认情况下,任何的页面都会被保护起来,访问者只有在被赋予某种角色的时候,才允许访问该角色“允许访问”的页面——也就是该角色在权限表中“明确”指明“可访问”的页面,而其他的页面,还是不允许访问。

“任何角色可进入”的控制器/页面

由于强制控制的情况下,访问者还是需要在某个页面进行登录等操作,才开始被赋予角色并通行系统,所以,需要将登录表单、错误提示等页面,设置成“任何角色可进入”。

在权限记录中,“任何角色可进入”的记录会如下标识:

INSERT INTO `pubgb_acl` VALUES ('5', '首页', 'main', 'index', 'SPANONYMOUS');
INSERT INTO `pubgb_acl` VALUES ('6', '登录', 'main', 'login', 'SPANONYMOUS');

指代是的“main/index”(首页)、“main/login”(登录)等页面,是任何人都可以访问的。

所以,如果访问者在没有被赋予角色前访问系统,那么将会弹出错误提示,并且转向到“main/login”进行登录操作。

读者可以想到,如果系统没有把首页和登录提示页面设置成“任何角色可进入”的页面,那么,将会形成死循环。
对比有限控制,强制控制是比较严格的权限控制模式,拒绝一切未经授权的访问,只有具备某权限的角色,才能访问对应的页面。

201103300719441237[1].jpg

通常,强制控制是用在“后台”类型的系统中,比如说公司内部OA系统,报表系统等。
INSERT INTO `pubgb_acl` VALUES ('1', '留言管理后台', 'admin', 'index', 'GBADMIN');
INSERT INTO `pubgb_acl` VALUES ('2', '删除留言', 'admin', 'del', 'GBADMIN');
INSERT INTO `pubgb_acl` VALUES ('3', '提交留言', 'main', 'post', 'GBUSER');
INSERT INTO `pubgb_acl` VALUES ('4', '提交留言', 'main', 'post', 'GBADMIN');
INSERT INTO `pubgb_acl` VALUES ('5', '首页', 'main', 'index', 'SPANONYMOUS');
INSERT INTO `pubgb_acl` VALUES ('6', '登录', 'main', 'login', 'SPANONYMOUS');
INSERT INTO `pubgb_acl` VALUES ('7', '查看留言', 'main', 'view', 'SPANONYMOUS');
INSERT INTO `pubgb_acl` VALUES ('8', '登出', 'main', 'logout', 'SPANONYMOUS');

从上面的记录可以看到:


  • “任何角色可进入”:main/index,main/login,main/view,main/logout
  • GBUSER:main/index,main/login,main/view,main/logout,main/post
  • GBADMIN:main/index,main/login,main/view,main/logout,main/post,admin/index,admin/del

因为是“强制控制”,“只有——有权限的角色——才可以访问”,所以在权限记录中“明确声明”可以让当前角色进入的页面之外,当前角色都不可以访问。

使用方式

1. 入口文件设置扩展点

'launch' => array( 
         'router_prefilter' => array(
                array('spAcl','maxcheck') // 开启强制的权限控制
         )
),

注意,“强制控制”是“maxcheck”,对比“有限控制”是“mincheck”。

2. 设置“任何角色可进入”的页面。这里设置了main/index,main/login,main/view,main/logout为“任何角色可进入”。

3. 设置错误提示

'ext' => array( // 扩展设置
        'spAcl' => array( // acl扩展设置
                'prompt' => array("lib_user", "acljump"),
        ),
)

4. 为GBUSER,GBADMIN设置权限记录,还是用之前的表,只不过换了记录。

这里可以看到,以下页面GBUSER角色是可以执行的:

GBUSER:main/index,main/login,main/view,main/logout,main/post

而以下的页面,GBUSER角色就无法执行了

admin/index,admin/del

“强制控制”流程图如下:

201103300721289889[1].jpg



2012-08-04 14:27:07

#2 jake

例子代码中:

控制器main的login函数中有这样一段获取MD5加密后字符串的代码



新版的spAcl中并无此函数,此函数存在于md5password中

先从本站取得md5password类库 http://www.speedphp.com/forum.php?mod=viewthread&tid=470

然后正确的代码应该是

$upass = spClass("md5password")->pwvalue();

2013-03-17 09:59:54