来源:http://trac.seagullproject.org/wiki/Howto/RolesAndPermissions

角色与权限

简介

访问Seagull资源的权限在很大程度上取决于用户是否是

  • 匿名用户
  • 通过身份验证的用户

验证

身份验证是通过一系列资料向系统证实自己身份的过程。Seagull的验证机制是通过数据库进行的。计划支持其它方式的验证,当LiveUser包被集成到SGL后,身份验证就可以使用LDAP,文本文件,POP3服务,RADIUS等等。

一旦身份进行了身份验证,Seagull便通过它的基于角色的授权机制对资源实行某些限制。

所有通过Seagull创建的界面或页面默认是允许匿名访问的。这是由配置设置决定的。在每一个模块的配置文件conf.ini中,有一个该模块的所有MGR列表,可以为每个MGR设置:

requiresAuth = false

如果你不让匿名用户访问某个MGR,可以将MGR的requiresAuth键设置成true。

授权

一旦用户通过了验证,那么在每一次页面执行时都会在应用程序控制器层次上进行全局的权限验证,即SGL_Manager::_authorise($mgrPerm, $mgrName, $input)。你可以在你的代码内进行其它的特殊的权限验证,也可以在模板内进行,但是应用程序控制器级的权限验证确保了当前已经验证用户有权限在模块的当前MGR内执行请求的方法。

注意:不建议将需要验证和不需要验证的方法放在同一个MGR内,将它们分开易于维护你的代码。如果你的MGR内的方法有的需要验证,而有的允许匿名访问,那么先创建一个不包含不需要验证的方法的MGR,然后再创建一个包含需要验证方法的MGR,这个MGR继承前面的MGR,这样就可以重用所有它的方法了。如:

FaqMgr (requiresAuth = false)
======
 - list

AdminFaqMgr (requiresAuth = true)
===========
 - add
 - edit
 - delete
 - ...

概述

Seagull默认提供了粗糙的权限管理,站点管理员只需要很少的设置就可以了。粗糙是指你可以在应用程序内控制哪些用户可以执行哪些方法。更加细颗粒的限制也是有可能的,比如你可以限制对某个方法内的某种内容的访问,或者限制对某个对象特定属性的访问,当然开发人员得自己实现这些功能的。

当你创建一个至少包含一个MGR的模块时,Seagull在user模块内提供了自动生成权限的工具。如果你的MGR有5个action,选择'Manage permissions'然后选择'detect and add'就会在permissions表内生成5新的记录,并生成你可以你的代码内使用的对应权限的常量。

perm records       id
============       ==
faqmgr_cmd_list    23
faqmgr_cmd_add     24
faqmgr_cmd_insert  25
faqmgr_cmd_edit    26
faqmgr_cmd_update  27

perm constants
==============
SGL_PERMS_FAQMGR_CMD_LIST
SGL_PERMS_FAQMGR_CMD_ADD
SGL_PERMS_FAQMGR_CMD_INSERT
SGL_PERMS_FAQMGR_CMD_EDIT
SGL_PERMS_FAQMGR_CMD_UPDATE

Seagull使用角色将权限分组。角色的典型例子是member,editor,admin等。在测试是否有权限访问某个资源时,你可以测试一个单独的权限(或你所创建的自定义的权限),或者只是测试这个用户是否属于某个角色,这个角色拥有目标权限。你也可以设置类权限,类权限可以让用户访问MGR内所有的action。使用这种方法可以非常容易给用户以访问某个特定模块的权限,或者是某个特定的MGR,或者是某个特定的action。 那么,请看:

  • guests: 如果一个MGR的配置文件如下设置,guests可以访问此MGR的任意内容
 requiresAuth = false
  • member角色默认安装时提供,只是作为一个简单的例子。所有member的用户将member角色的权限复制了一份并连同usr_id到user_permission表。所以你可以把角色当成权限的模板,而每个用户的权限集是它们所属角色的一个特例。这样每个用户的权限可以根据需要修改,换句话说,他们可以在角色权限集的基础上添加或删除权限,所以两个同属member角色或其它任何角色的用户不一定具有一样的权限集。
  • admin:完全没有权限限制,他们可以执行任何操作,你可以称它为伪角色.

所以正如上面所说的:

  • 权限对应于MGR类中action方法,即,如果你有一个PiggyMgr类,包含如下action方法:_goesToMarket(),_staysHome()和_eatsRoastBeef(),每个方法对应一个保存在数据库中的二进制权限,在客户端代码中用一个常量表示。
  • 在系统中可以有任意数量的权限项/角色
  • 角色可以被复制
> 2) Is the only need for loading all permissions (via
> $dao->retrieveAllPerms()) so that the perm check in
> Manager->process() can fetch the perm_id value from the global perms array
> and then check that it is in the user's perm array? e.g. 
> 	
> $perm = @constant('SGL_PERMS_' . strtoupper($className . $methodName));
> ...
> if (SGL_Session::hasPerms($perm) {
>     $this->$methodName($input, $output);
> }

对,要知道$dao→retrieveAllPerms()是被SGL_Process_SetupPerms()任务调用的,这个任务在第一次请求时创建了全局数组。如果你打开了缓存,它会将权限数组缓存到磁盘以备后续请求使用。

权限

命名约定

命名约定是managerclass_cmd_method.比如faq模块中有个叫FaqMgr的manager,那么他对应的权限如下

  • faqmgr_cmd_list
  • faqmgr_cmd_add
  • faqmgr_cmd_insert
  • faqmgr_cmd_delete

一个方法一个权限

类范围的权限

如果你想准许一些用户有权使用一个类的所有方法,你必须调用它modulmgr,再以faq模块为例,它将是faqmgr.

检查自定义权限

有时在你的模块中你需要检查自定的权限,如MEMBERSHIP_GOLD。基于权限验证结果的基础上根据用户权限选择一个不同的模板来显示或隐藏额外的功能。权限可以通过调用静态的SGL_Session方法来验证。

boolean SGL_Session::hasPerms(int $permId)

所有的权限用一个常量代表,所以在实际例子中你可以你这样使用:

if (SGL_Session::hasPerms(SGL_PERMS_MEMBERSHIP_GOLD)) {

 // specific privilege

}

添加权限

使用detect & add函数,你可以很容易地为系统添加权限.

它扫描所有已安装的模块,并输出一系列新的权限,你可以通过少数的鼠标点击来添加它们.

删除孤儿权限

使用删除孤儿函数是相当简单的.它将显示一系列旧的权限,你可以通过少数的鼠标点击来删除.

角色

创建角色

一个角色仅仅是某些权限的一个组,当创建新的用户时,这个新的用户就采纳了所属角色‘模板’的所有权限,然后你可以根据需要增加或删除这个用户的个别的权限项.注意:当一个角色的权限改变时,已创建的用户的权限不会随之改变.

为站点创建新的角色,只要使用Users and Security模块的Role部分的工具.很简单的:

  • 复制'member'角色
  • 根据自己需要重命名
  • 点击角色的'permissions → change'
  • 从左框中移动新的权限到右框中,并点击'提交'

注意:admin按钮在页面的顶端,有时被导航栏隐藏 - 你或许只能修改默认的导航栏

同步权限已被更新的用户

由于它所包含的是权限而不是角色,它被保存到基于每个用户,修改权限后,你必须同步用户的角色.

使用角色与权限同步的功能就可以执行.

你可以选择要你要同步的用户,如果你将他们同步到当前或其它的角色,或你想添加丢失的权限,删除额外的权限或两者兼有.

对文章中应用权限

Q:是否有方法通过文章分类控制权限?

A:Publisher模块有一个权限管理类。你需要决定你的文章以哪属于哪个分类,选择Publisher's Categories管理链接,删除你不想让访问这类文章的角色的权限。

目前,这种方法只适合浏览文章,不适合编辑.

扩展权限角色功能

开发者可以指定一种更灵活的权限方法,如,一组权限必须被应用到某个角色的所有用户,而不是为每个用户做一份拷贝。按下列步骤进行:

 1. 在Config -> Session中设置权限检索方法为getPermsByUser
 2. 复制一份user模块,这样你可在此基础在修改UserDAO
 3. 创建一个新的modules文件夹,如modulesFoo(译者注:这个文件夹用来替代SGL的modules文件夹)
 4. 在Config -> General中设置modulesOverride目录为modulesFoo
 5. 在你的UserDAO中注释掉为每个用户复制权限的代码。请看 UserDAO::addUser() 

做完这种修改后,你可以删掉user_permission表

 
howto/rolesandpermissions.txt · 最后更改: 2010/05/30 00:21 (外部编辑)
 
Except where otherwise noted, content on this wiki is licensed under the following license:GNU Free Documentation License 1.2