安全组件
难易程度: 进阶者
技能要求:
主题知识覆盖了前面“内容组件”一章;
了解诸如接口、ZCML以及一些安全概念,例如权限、角色和主体(可选)。
问题/任务:
为了运行我们的留言簿,我们必须做一些基本的安全声明,不过此时它没有真地表现出是一个安全系统。一些最终用户查看需要zope.ManageContent权限,这儿并没有这种角色被定义。
解决方案:
Zope3提供了一套非常灵活的安全机制。许可和主体是两个基本的概念。许可是打开一个具体功能的敲门砖。例如,我们可能需要zope.View 的许可来看一个消息的详细界面。另一方面,主体是执行动作的系统代理。最通用的主体实例就是一个系统用户。我们现在的目标就是把许可授权给主体,这是安全策略子系统的职责。
Zope 3 不运行任何的特殊的安全策略。相反它鼓励站点系统管理员小心的选择安全策略并且使用一个最适合他们需求的策略。 Zope 3 提供了一个缺省的安全策略( zope.app.securitypolicy)支持角色内容。角色就像顶在人们头上的帽子,正如Jim Fulton所说,可以被看作是一个许可的集合,一个单独用户能有不同的帽子,但是只能在同一时间内戴一个帽子。 比较突出的角色实例包括“editor” 和“administrator”。因此,缺省的安全策略支持许可映射到主体,许可对角色和角色对主体。这章将用缺省的安全策略设置安全,但是我认为把这章标为安全策略详解更为合适。
第一个任务将定义一个许可并且用这些新的许可改变已经存在的指令。工作会显得很单调,但是需要小心,由于这些工作显得很重要,因为安全的质量就取决该工作了。当做这这些工作时候, 丢三落四的情况会经常在您身上发生,因此设置权限时要显得果断。然后将给使用缺省安全策略的站点管理员定义角色和授权许可。最后角色将授予给一些测试的用户。
当您看完这章后,您将会发现,对象安全并不需要对已经存在的Python代码做任何更改,因为所有的一切已经通过ZCML配置好了。因此安全配置完全可以抛开Python代码,通过使用ZCML来配置,这也是使用Zope 3 的优点(在与Zope 2比较时您会得到更多的信息)。
第I步: 声明许可
相对于Zope 2,许可必须被明确地定义,对于我们的留言簿而言,它有足够能力定义如下四个基本许可:
View - 允许用户访问留言簿和消息数据。每个一般的留言簿用户都将有这个许可。
Add - 让用户创建(IE)一个消息并且把它加到留言簿或者另一个消息。注意每个一般用户都允许添加,因为张贴和回复应该是被允许的。
Edit - 编辑内容(在内容已经创建后)仅仅是留言簿编辑者拥有的许可,因为我们不想一般用户能够操作创建后的张贴内容。
Delete - 编辑者必须能够去除消息,因此删除许可可以分配给她。注意这个许可不允许编辑者从文件夹或其它容器删除留言簿对象。
让我们现在定义许可。注意:它们一定在配置文件的最开始出现, 当其他指令 (该指令将会使用到许可) 被运行的时候以便他们将会发生作用。在这里您应该把四条指令加到您的主要 configure.zcml 文件里:
6
11
16
]]>
zope:permission指令在global permission registry里定义和创建了一个新的许可。对这个许可而言,ID应该是一个独一无二名称,因此给名称一个前缀应该是一个不错的主意,像 book.messageboard. 这种情况下,注意ID必须是一个有效的URI或点名称,如果这里没有点,一个ValidationError将被引发。ID也被用于下面配置步骤的标识符。许可的标题(title)将被用在用户界面中标识许可,描述则是像文档一样长的解释,ID和title都是被要求的属性。
第II步: 使用许可
既然我们已经定义这些许可, 现在就让我们使用它们; 让我们从主要的留言簿配置文件开始 (. messageboard/configure.zcml) 。在下面的初排中我们只使用所涉及许可的许可名称的最后一部分,停掉book.messageboard。然而,完整的ID必须被指定配置执行。
使用View许可改变在 MessageBoard 内容指令的需求陈述(42行)。让所有的留言用户都能访问描述和条目。改变64行。
在46行改变权限给编辑(Edit),因为只有留言簿管理员能改变MessageBoard对象的任何属性。
所有的容器功能只要求查看(view)许可,因此在68行改变权限给查看(view)。心里还是有些不安,因为这包括了阅读和写入方法,但它已经足够起示范作用了。
在第72行指定权限,我们需要设置能够增加消息的许可。
现在让我们到browser配置文件(messageboard/browser/configure.zcml)里修正许可。
第11行:留言簿增加表单的许可;第18行:添加菜单条目;第27行:编辑表单不要改变,因为只有管理员才能管理留言簿。
由于我们想让每个用户都能看到留言簿里的留言,第33行上的许可应该是 View。因为内容视图意味着管理,只有编辑许可的主体才能看到它(34行)。最后,您需要添加消息到留言簿的添加许可(第35行)。这一样适用于消息容器视图查看许可(第84-86行)。
由于所有用户都应该能看到消息线索和详细的消息,第43行、94行和106行的许可都应该是View。
在61行您应该改变许可为Add,因为您只是允许消息被添加到留言簿,如果用户有这个许可。这一样适用于在68行上的添加菜单。
在78行上,如果用户有Edit许可,确信用户只能访问到edit界面。
这就是我们想介绍给您的东西。如果您现在重启Zope 3 ,您将不能访问MessageBoard 和Message的实例。因为我们需要创建下一些角色并且分配许可给他们。
第III步: 角色的声明
Zope 3 默认的安全策略才有角色的声明。 其它的安全策略甚至可能没有有角色这个概念。因此,角色声明和许可的授权不应该是您软件包的一部分。为了简单起见,我们把把它保存在一个地方,我们将在security.zcml文件中存储policy-specific安全配置。对于我们的留言簿软件包我们只需要两个角色,"User"和"Editor",如下:
5
6
]]>
等价于zope:permission指令,zope:role指令以global role registry创建和注册了一个新的角色。在整个配置过程中,ID必须是一个区分角色独一无二的标识符。id和title(标题)都是必需的。
下一步我们授予新许可给新角色,i.e. 创建一个角色许可地图。当编辑器被允许执行所有许可的时候,用户应该只会添加和查看消息。
5
9
13
]]>
zope:grant指令是非常的复杂,因为它允许三种不同类型的安全映射。它允许您分配一个许可给一个主体,一个角色给一个主体,以及一个许可给一个角色。因此指令有三个选择参数:permission(许可)、 role(角色), 和principal(主体)。三个参数中的两个参数必须被指定,并且使它成为一个有效指令。三个安全对象通过它们的ID被指定。
最后,您必须在您其它的配置中包括security.zcml文件。在ZOPE3/principals.zcml文件里添加如下包含指令:
]]>
我们之所以把它放在这儿是我们想让此文件基于安全策略显得更加明显。当我们分配许可给角色时,我们想要所有可能的许可,并且这些系统必须能定义。因为principals.zcml文件是最后一个被估算的ZCML,这是放置声明最好的地方。
第IV步: 分配角色给主体
再次开始我们软件包的工作,我们现在必须把角色和一些主体连接起来。我们将创建两个名叫boarduser和boardeditor的新主体。为了做这些工作,到Zope 3根目录并且添加如下行到principals.zcml文件中:
6
10
11
16
20
]]>
zope:principal指令在系统里创建和注册一个新的主体/用户。与所有的安全对象一样,id和title(标题)必须被要求。我们也能指定一个描述(description)。除了这三个属性之外,开发者必须为用户指定登陆名和密码(文本),这当然用于认证。
注意:您可能想要授予book.messageboard.User角色给zope.anybody主体,以致于每个人都能查看和添加消息。
zope.anybody主体是一个未被认证的主体,使用 zope:unauthenticatedPrincipal 指令定义,有与zope:principal 指令相同的三个基本属性,但是不接受登陆(login)和密码(password)属性。
现在您的系统应该是安全和可用的。如果您现在重启Zope 3 ,您将看见只有留言簿编辑者能自由地操纵对象。 (当然您必须以编辑者身份登录)。
练习
现在我们回过头来看,把book.messageboard.User 角色给book.messageboard.View 和book.messageboard.Add 的许可真的是一个很差的主意。因为您不能在匿名用户和能够添加消息的用户之间进行区分。添加另一个叫book.messageboard.Viewer 的角色并且使details.html和thread.html 的 view (查看)可用。然后把这个角色授予给没有认证的主体(任何人)并且修改这个主体能够真正地访问这些视图。
(涉及到前面的问题)另一方面,创建一个代替角色,我们将授予View许可直接给匿名主体。并且证明这些没有认证的用户能够看这些视图。