09_第八章迭代5用户访问控制

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

第八章:迭代5:用户访问控制像我们前面制作的TrackStar应用程序这样基于用户的web应用程序中,通常需要针对谁对某一功能提出访问请求进行访问控制。我们所说的用户访问控制是指在一个较高的层次上,当访问请求被提出时一些需要被思考的问题,例如:请求的提出者是谁?提出请求的用户是否有足够的权限访问该功能?上述问题的答案可以帮助应用程序做出适当的响应。在上次迭代中完成的工作使得应用程序有能力提出第一个问题。我们的基础用户管理应用扩展了应用程序的用户认证流程,使之可以使用数据库内的资料。应用程序现在允许用户建立自己的认证信息,并且在用户登录时使用储存在数据库内的信息进行匹配。在用户成功登录后,应用程序就知道接下来的一系列请求是谁提出的。本次迭代的核心任务是帮助应用程序回答第二个问题。一旦用户提供了足够的认证信息后,应用程序需要找到一种合适的方法去判断用户是否有足够的权限去执行要求的操作。我们将利用Yii的用户访问控制中的一些特性来扩展我们的基本授权模型。Yii即提供了一个简单的访问控制过滤器,也提供了一个更先进的RBAC(基于角色的访问控制)体系,来帮助我们完成授权需求。我们将在TrackStar应用程序中用户访问需求的实现中仔细观察这2点。迭代计划当我们在第3章第一次介绍我们的TrackStar应用程序时,我们曾提及,这个应用程序拥有2个高级别用户类型:匿名用户和认证用户。这是一个小小的区别基于成功登录的用户和未登录的用户。我们也介绍过用户在同一个Project中扮演不同角色的想法。针对一个Project我们建立了如下的三类角色模型:ProjectOwner(被赋予所有权限访问此Project的管理功能)ProjectMember(被赋予一定权限访问此Project的特性和功能)ProjectReader(只有读取Project相关内容的权限,没有任何修改级权限)这次迭代的重点是实施方法来管理这个应用程序中用户的访问控制权限。我们需要一个方法来建立我们的角色和权限,并且分发给用户,同时制定我们期望对每个角色施加的访问控制规则。为了这个目标,我们需要标明所有我们将在本次迭代中完成的项目细节。下面的列表是这样一个项目列表:制定一个策略来强制用户在获得访问任何Project或Issue相关功能前,必须登录建立用户角色并且使之与一个特殊的功能权限对应制定一个为用户分配角色的机制(包含角色相关的权限)确保我们的角色权限结构针对每一个Project独立存在(也就是说,允许用户在不同的项目拥有不同的权限)制定一个让用户和项目,同时也和项目中的角色相关联的机制实施适当的认证访问检测,使得应用程序可以针对基于不同用户权限进行允许或拒绝访问操作幸运的是,Yii内部有大量内部功能可以帮助我们完成这一需求。所以,让我们大干一场吧。运行已存在的测试套件如常,是时候运动一下了,我们需要运行一次所有已存在的单元测试,来确保测试可以通过:SHELL代码或屏幕回显:%cdWebRoot/protected/tests/%phpunitunit/PHPUnit3.4.12bySebastianBergmann.................Time:3secondsOK(10tests,27assertions)一切都没有问题,所以我们可以开始本次旅程了。访问控制过滤器我们曾经在第三次迭代的时候介绍过过滤器,当时我们使用它来鉴别项目上下文关系,当处理Issue相关CRUD操作时。Yii框架提供的过滤器被叫做accessControl(访问控制)。这个过滤器可以被直接使用在控制器类中,提供一种授权方案来验证用户是否可以使用一个特定的控制器下的行为。实际上,细心的读者应该能想起,我们在第六章使用filterProjectContext过滤器时,我们曾发现过,访问控制过滤器当时已经存在于IssueController和ProjectController类的过滤器列表中,像下面的样子:PHP代码:/***@returnarrayactionfilters*/publicfunctionfilters(){returnarray('accessControl',//performaccesscontrolforCRUDoperations);}上面的代码包含在由Gii代码生成器在生成Issue和ProjectAR类的脚手架CRUD操作时,自动生成的代码里的。默认的实现方法是设置为允许任何人观看一个已经存在Issue和Project项目的列表。然后,它只允许认证用户进行新建和更新操作,进一步限制帐号为admin的用户享有删除行为。你也许还记得当我们第一次对Project实施CRUD操作时,我们必须登录才可以执行操作。同样的情形发生在对Issues和Users的操作上。这种机械式的授权和访问模式就是由过滤器accessControl实现的。让我们仔细观察一下在ProjectController.php文件中的这种实现方式。有2个相关访问控制实现方法在这个文件中,ProjectController:filters()和ProjectController::accessRules()。第一个方法的代码如下:PHP代码:/***@returnarrayactionfilters*/publicfunctionfilters(){returnarray('accessControl',//performaccesscontrolforCRUDoperations);}下面是第二个方法的代码:PHP代码:/***Specifiestheaccesscontrolrules.*Thismethodisusedbythe'accessControl'filter.*@returnarrayaccesscontrolrules*/publicfunctionaccessRules(){returnarray(array('allow',//allowalluserstoperform'index'and'view'actions'actions'=array('index','view'),'users'=array('*'),),array('allow',//allowauthenticatedusertoperform'create'and'update'actions'actions'=array('create','update'),'users'=array('@'),),array('allow',//allowadminusertoperform'admin'and'delete'actions'actions'=array('admin','delete'),'users'=array('admin'),),array('deny',//denyallusers'users'=array('*'),),);}filters()方法对我们来说已经非常熟悉了。我们在这里申明所有将在这个控制器类里使用的过滤器。在上面的代码中,我们只有一个accessControl,引用了一个由Yii框架提供的过滤器。这个过滤器调用定义了如何驱动相关访问限制规则的accessRules()方法。在前面提到的accessRules()方法中,有4条规则被申明。每一条都以数组形式存在。该数组的第一个元素是allow(通过)或deny(拒绝)。分别标识了获得或拒绝相关访问。剩下的部分由name=value键值对组成,申明了规则里剩余的参数。让我们观察一下前面定义的第一条规则:PHP代码:array('allow',//allowalluserstoperform'index'and'view'actions'actions'=array('index','view'),'users'=array('*'),),这条规则允许任何用户执行控制器的index和viewactions(行为)。星号‘*’特殊字符泛指所有用户(包括匿名,已认证,和其他类型)。第二条规则被定义成如下形式:PHP代码:array('allow',//allowauthenticatedusertoperform'create'and'update'actions'actions'=array('create','update'),'users'=array('@'),),这条规则允许认证用户(已登录)执行控制器的create和updateactions。‘@’特殊字符泛指所有已认证用户。下面是第三条规则:PHP代码:array('allow',//allowadminusertoperform'admin'and'delete'actions'actions'=array('admin','delete'),'users'=array('admin'),),这里申明一个用户名为admin的特殊用户,被允许执行控制器的actionAdmin()和actionDelete()actions。第四条规则如下定义:PHP代码:array('deny',//denyallusers'users'=array('*'),),它拒绝了所有用户执行所有控制器的的所有action。定义访问规则的时候可以使用一些contextparameters(内容参数)。前面提到的规则定义了行为和用户来组成规则的内容,下面是一个完整的参数列表:Controllers(控制器):这条规则指定了一个包含多个控制器ID的数组,来指明哪些规则需要被应用。Roles(角色):这条规则指定了一个将被规则使用的授权列表(包括角色,操作,权限等)。这些是为RBAC的一些功能服务的,我们将在下一个部分进行讨论。Ips(IP地址):这条规则指定了一组可以被施加到规则的客户端IP地址。Verbs(提交类型):这条规则制定了可以被施加到规则的HTTP请求类型。Expression(表达式):这个规则指定了一个PHP表达式,这个表达式的值被用来决定这个规则是否应该被使用。Actions(行为):这个规则指定了需要被规则匹配的对应actionID(行为ID)的方法。Users(用户):这个规则指定了应该被施加规则的用户。登录当前项目的用户名作为被匹配项。3个特殊字符可以被使用:o*:任何用户o?:匿名用户o@:登录用户/认证用户访问规则按照其被申明的顺序一条一条的被评估。第一条规则与当前模型进行匹配,来判断授权结果。如果当前规则是一个allow的,这个行为(action)可以被执行;如果是一个deny规则,这个action无法被执行;如果没有规则和内容匹配,这个action仍然可以被执行。这是第四条被定义的原因。如果我们不在我们的认证列表末端定义一条deny全部用户全部action的规则,我们就无法完成预期的访问控制。拿第二个规则来举例,所有通过认证的用户可以执行create和updateactions。但是它并不会拒绝匿名用户的请求。它对匿名用户熟视无睹。这里第四条规则确保所有和上面3条不匹配的请求都被拒绝掉。当这些都完成后,修改我们的应用程序来拒绝匿名用户访问所有的Project,Issue和user相关的功能,绝对小菜一叠。我们需要做的是将用户数组的特殊字符’*’替换为’@’。这将只允许认证用户访问对应控制器的actionIndex()和actionView()方法。所有其他actions都拒绝认证用户访问。对我们的控制器进行如下修改。打开下面3个文件:ProjectController.php,IssueController.php和userController.php,并且如下修改第一条访问控制规则:PHP代码:array('allow',//allowonlyauthenticateduserstoperform'index'and'view'actions'actions'=array('inde

1 / 45
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功