yii Controller 访问控制过滤器 使用 摘记

来源:互联网 发布:小语网络加速器下载 编辑:程序博客网 时间:2024/05/17 00:57
访问控制过滤器 
我们曾经在第三次迭代的时候介绍过过滤器,当时我们使用它来鉴别项目上下文关系,当处理Issue相关
CRUD操作时。Yii框架提供的过滤器被叫做 accessControl(访问控制)。这个过滤器可以被直接使用在
控制器类中,提供一种授权方案来验证用户是否可以使用一个特定的控制器下的行为。实际上,细心的读
者应该能想起,我们在第六章使用filterProjectContext过滤器时,我们曾发现过,访问控制过滤器当时
已经存在于 IssueController和ProjectController类的过滤器列表中,像下面的样子: 
/** 
* @return array action filters 
*/  
public function filters() { 
    return array(  
        'accessControl', 
        // perform access control for CRUD operations  
    ); 

上面的代码包含在由Gii代码生成器在生成Issue和Project AR类的脚手架CRUD操作时,自动生成的
代码里的。 
默认的实现方法是设置为允许任何人观看一个已经存在Issue和Project项目的列表。然后,它只允许认
证用户进行新建和更新操作,进一步限制帐号为 admin的用户享有删除行为。你也许还记得当我们第一
次对Project实施CRUD操作时,我们必须登录才可以执行操作。同样的情形发生在对 Issues和Users
的操作上。这种机械式的授权和访问模式就是由过滤器accessControl实现的。让我们仔细观察一下在 
ProjectController.php文件中的这种实现方式。 
有2个相关访问控制实现方法在这个文件中,ProjectController:filters()和
ProjectController::accessRules()。第一个方法的代码如下: 
/**  
* @return array action filters  
*/ 
public function filters()  

    return array(  
        'accessControl', // perform access control for CRUD operations 
    ); 

下面是第二个方法的代码: 
/** 
*Specifies the access control rules. 
*This method is used by the 'accessControl' filter. 
*@return array access control rules 
*/ 
  
public function accessRules() 

    return array( 
        array('allow', // allow all users to perform 'index' and'view' actions 
            'actions'=>array('index','view'), 
            'users'=>array('*'), 
        ), 
  
        array('allow', // allow authenticated user to perform 'create' and 'update' actions 
            'actions'=>array('create','update'), 
            'users'=>array('@'), 
        ), 
  
        array('allow', // allow admin user to perform 'admin' and 'delete' actions 
            'actions'=>array('admin','delete'),  
            'users'=>array('admin'), 
        ),  
  
        array('deny', // deny all users 
            'users'=>array('*'), 
        ), 
    ); 

filters()方法对我们来说已经非常熟悉了。我们在这里申明所有将在这个控制器类里使用的过滤器。在上
面的代码中,我们只有一个 accessControl,引用了一个由Yii框架提供的过滤器。这个过滤器调用定义
了如何驱动相关访问限制规则的accessRules()方法。 
在前面提到的accessRules()方法中,有4条规则被申明。每一条都以数组形式存在。该数组的第一个元
素是allow(通过)或deny(拒绝)。分别标识了获得或拒绝相关访问。剩下的部分由 name=>value键值
对组成,申明了规则里剩余的参数。 
让我们观察一下前面定义的第一条规则: 
array('allow', // allow all users to perform 'index' and 'view' actions 
    'actions'=>array('index','view'),  
    'users'=>array('*'), 
), 
这条规则允许任何用户执行控制器的index 和view actions(行为)。星号„*‟特殊字符泛指所有用户(包
括匿名,已认证,和其他类型)。 
第二条规则被定义成如下形式: 
array('allow', // allow authenticated user to perform 'create' and 'update' actions 
    'actions'=>array('create','update'),  
    'users'=>array('@'), 
), 
这条规则允许认证用户(已登录)执行控制器的create和update actions。„@‟特殊字符泛指所有已认
证用户。 
下面是第三条规则: 
array('allow', // allow admin user to perform 'admin' and 'delete' actions 
    'actions'=>array('admin','delete'),  
    'users'=>array('admin'), 
), 
这里申明一个用户名为admin的特殊用户,被允许执行控制器的actionAdmin()和actionDelete()操作
方法。 
第四条规则如下定义: 
array('deny', // deny all users  
    'users'=>array('*'), 
), 
它拒绝了所有用户执行所有控制器的的所有action。 
定义访问规则的时候可以使用一些 context parameters(内容参数)。前面提到的规则定义了行为和用户
来组成规则的内容,下面是一个完整的参数列表: 
  Controllers(控制器):这条规则指定了一个包含多个控制器ID的数组,来指明哪些规则需要被应用。 
  Roles(角色):这条规则指定了一个将被规则使用的授权列表(包括角色,操作,权限等)。这些是为RBAC
的一些功能服务的,我们将在下一个部分进行讨论。 
  Ips(IP地址):这条规则指定了一组可以被施加到规则的客户端IP地址。 
  Verbs(提交类型):这条规则制定了可以被施加到规则的HTTP请求类型。 
  Expression(表达式):这个规则指定了一个PHP表达式,这个表达式的值被用来决定这个规则是否应该
被使用。 
  Actions(行为):这个规则指定了需要被规则匹配的对应action ID(行为ID)的方法。 
  Users(用户):这个规则指定了应该被施加规则的用户。登录当前项目的用户名作为被匹配项。3个特殊字
符可以被使用: 
o  *:任何用户 
o  ?:匿名用户 
o  @:登录用户/认证用户 
访问规则按照其被申明的顺序一条一条的被评估。第一条规则与当前模型进行匹配,来判断授权结果。如
果当前规则是一个allow的,这个行为(action)可以被执行;如果是一个deny规则,这个action无法被
执行;如果没有规则和内容匹配,这个action仍然可以被执行。这是第四条被定义的原因。如果我们不在
我们的认证列表末端定义一条deny全部用户全部action的规则,我们就无法完成预期的访问控制。拿第
二个规则来举例,所有通过认证的用户可以执行create和update actions。但是它并不会拒绝匿名用户
的请求。它对匿名用户熟视无睹。这里第四条规则确保所有和上面3条不匹配的请求都被拒绝掉。 
当这些都完成后,修改我们的应用程序来拒绝匿名用户访问所有的Project,Issue和user相关的功能,
绝对小菜一叠。我们需要做的是将用户数组的特殊字符‟*‟替换为‟@‟。这将只允许认证用户访问对应控制
器的actionIndex()和actionView()方法。所有其他actions都拒绝认证用户访问。 
对我们的控制器进行如下修改。打开下面3个文件:ProjectController.php, IssueController.php和
userController.php,并且如下修改第一条访问控制规则: 
array('allow', // allow only authenticated users to perform 'index' and 'view' actions 
    'actions'=>array('index','view'),  
    'users'=>array('@'), 
), 
完成这些修改后,应用程序会在访问Project, Issue或User的任何功能前要求登录。我们依然允许匿名
用户访问SiteController类的action方法,这是因为我们的登录方法存在于这个类中。我们必须允许匿
名用户访问登录页。