Oneleaf讨论 | 贡献2007年5月31日 (四) 09:28的版本 (新页面: == Chapter 16: Securing Components(第 16 章:保证组件安全) == ---- 原文出处:[http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/FrontPage/Zope3Book The ...)

(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳转至: 导航, 搜索

Chapter 16: Securing Components(第 16 章:保证组件安全)

原文出处:The Zope 3 Developers Book - An Introduction for Python Programmers

原文作者:StephanRichter, zope.org



校对人员:Leal, FireHare

适用版本:Zope 3





        • Be Knowledgable about topics covered in the previous chapters of the “Content Components” section.
        • Be familiar with interfaces, ZCML and some of the security concepts, such as permissions, roles and principals.


While we had to make basic security assertions in order to get our message board to work, it does not really represent a secure system at this point. Some end-user views require the `zope.ManageContent` permission and there are no granular roles defined.


Zope 3 comes with a flexible security mechanism. The two fundamental concepts are permissions and principals. Permissions are like keys to doors that open to a particular functionality. For example, we might need the permission zope.View to look at a message’s detail screen. Principals, on the other hand, are agents of the system that execute actions. The most common example of a principal is a user of the system. The goal is now to grant permissions to principals, which is the duty of another sub-system known as the securitypolicy.
Zope3提供了一套非常灵活的安全机制。许可和主体是两个基本的概念。许可是打开一个具体功能的敲门砖。例如,我们可能需要zope.View 的许可来看一个消息的详细界面。另一方面,主体是执行动作的系统代理。最通用的主体实例就是一个系统用户。我们现在的目标就是把许可授权给主体,这是安全策略子系统的职责。

Zope 3 does not enforce any particular security policy. In contrary, it encourages site administrators to carefully choose the security policy and use one that fits their needs best. The default Zope 3 distribution comes with a default security policy ( zope.app.securitypolicy) that supports the concept of roles. Roles are like hats people wear, as Jim Fulton would say, and can be seen as a collection of permissions. A single user can have several hats, but only wear one at a time. Prominent examples of roles include “editor” and “administrator”. Therefore, the default security policy supports mappings from permissions to principals, permissions to roles, and roles to principals. This chapter will use the default security policy to setup the security, but will clearly mark the sections that are security policy specific.
Zope 3 不运行任何的特殊的安全策略。相反它鼓励站点系统管理员小心的选择安全策略并且使用一个最适合他们需求的策略。 Zope 3 提供了一个缺省的安全策略( zope.app.securitypolicy)支持角色内容。角色就像顶在人们头上的帽子,正如Jim Fulton所说,可以被看作是一个许可的集合,一个单独用户能有不同的帽子,但是只能在同一时间内戴一个帽子。 比较突出的角色实例包括“editor” 和“administrator”。因此,缺省的安全策略支持许可映射到主体,许可对角色和角色对主体。这章将用缺省的安全策略设置安全,但是我认为把这章标为安全策略详解更为合适。

The first task will be to define a sensible set of permissions and change the existing directives to use these new permissions. This is a bit tedious, but it is important that you do this carefully, since the quality of your security depends on this task. While doing this, you usually discover that you missed a permission and even a role, so do not hesitate to add some. That is everything the programmer should ever do. The site administrator, who uses the default security policy, will then define roles and grant permissions to them. Finally the roles are granted to some users for testing.
第一个任务将定义一个许可并且用这些新的许可改变已经存在的指令。工作会显得很单调,但是需要小心,由于这些工作显得很重要,因为安全的质量就取决该工作了。当做这这些工作时候, 丢三落四的情况会经常在您身上发生,因此设置权限时要显得果断。然后将给使用缺省安全策略的站点管理员定义角色和授权许可。最后角色将授予给一些测试的用户。

Securing an object does not require any modification to the existing Python code as you will see going through the chapter, since everything is configured via ZCML. Therefore security can be completely configured using ZCML, leaving the Python code untouched, which is another advantage of using Zope 3 (in comparison to Zope 2, for example).
当您看完这章后,您将会发现,对象安全并不需要对已经存在的Python代码做任何更改,因为所有的一切已经通过ZCML配置好了。因此安全配置完全可以抛开Python代码,通过使用ZCML来配置,这也是使用Zope 3 的优点(在与Zope 2比较时您会得到更多的信息)。

16.1 Step I: Delcarations of Permissions(16.1 步骤 I:权限声明)

Other than in Zope 2, permissions have to be explicitly defined. For our message board it will suffice to define the following four basic permissions:
相对于Zope 2,许可必须被明确地定义,对于我们的留言簿而言,它有足够能力定义如下四个基本权限:

  • View - Allow users to access the data for message boards and messages. Every regular message board User is going to have this permission.
    View - 允许用户访问留言簿和消息数据。每个一般的留言簿用户都将有这个许可。
  • Add - Allows someone to create (i.e. post) a message and add it to the message board or another message. Note that every regular User is allowed to do this, since posting and replying must be possible.
    Add - 让用户创建(比如发送)一个消息并且把它加到留言簿或者另一个消息。注意每个一般用户都允许添加,因为张贴和回复应该是被允许的。
  • Edit - Editing content (after it is created) is only a permission the message board Editor possesses (for moderation), since we would not want a regular user to be able to manipulate posts after creation.
    Edit - 编辑内容(在内容已经创建后)仅仅是留言簿编辑者拥有的许可,因为我们不想一般用户能够操作创建后的张贴内容。
  • Delete - The Editor must be able to get rid of messages, of course. Therefore the Delete permission is assigned to her. Note that this permission does not allow the editor to delete `MessageBoar`d objects from folders or other containers.
    Delete - 编辑者必须能够去除消息,因此删除许可可以分配给她。注意这个许可不允许编辑者从文件夹或其它容器删除留言簿对象。

Let’s define the permissions now. Note that they must appear at the very beginning of the configuration file, so that they will de defined by the time the other directives (that will use the permissions) are executed. Here are the four directives you should add to your main configure.zcml file。让我们现在定义许可。注意:它们一定在配置文件的最开始出现, 当其他指令 (该指令将会使用到许可) 被运行的时候以便他们将会发生作用。在这里您应该把四条指令加到您的主要 configure.zcml 文件里:

1  <permission
2      id="book.messageboard.View"
3      title="View Message Board and Messages"
4      description="View the Message Board and all its content."
5      />
6  <permission
7      id="book.messageboard.Add"
8      title="Add Message"
9      description="Add Message."
10      />
11  <permission
12      id="book.messageboard.Edit"
13      title="Edit Messages"
14      description="Edit Messages."
15      />
16  <permission
17      id="book.messageboard.Delete"
18      title="Delete Message"
19      description="Delete Message."
20      />

The zope:permission directive defines and creates a new permission in the global permission registry. The id should be a unique name for the permission, so it is a good idea to give the name a dotted prefix, like book.messageboard. in this case. Note that the id must be a valid URI or a dotted name - if there is no dot in the dotted version, a `ValidationError` will be raised. The id is used as identifier in the following configuration steps. The title of the permissions is a short description that will be used in GUIs to identify the permission, while the description is a longer explanation that serves more or less as documentation. Both the id and title are required attributes.
zope:permission指令在global permission registry里定义和创建了一个新的许可。对这个许可而言,ID应该是一个独一无二名称,因此给名称一个前缀应该是一个不错的主意,像 book.messageboard. 这种情况下,注意ID必须是一个有效的URI或点名称,如果这里没有点,一个`ValidationError`将被引发。ID也被用于下面配置步骤的标识符。许可的标题(title)将被用在用户界面中标识许可,描述则是像文档一样长的解释,ID和title都是被要求的属性。

16.2 Step II: Using the Permissions(16.2 步骤 II:使用权限)

Now that we have defined these permissions, we also have to use them; let’s start with the main message board configuration file ( messageboard/configure.zcml). In the following walk-through we are only going to use the last part of the permission name to refer to the permission, leaving off book.messageboard. However, the full id has to be specified for the configuration to execute.
既然我们已经定义这些许可, 现在就让我们使用它们; 让我们从主要的留言簿配置文件开始 (. messageboard/configure.zcml) 。在下面的初排中我们只使用所涉及许可的许可名称的最后一部分,停掉book.messageboard。然而,完整的ID必须被指定配置执行。

  • Change the first require statement of in the `MessageBoard` content directive to use the View permission (line 42). This makes the description and the items accessible to all board users. Similarly, change line 64 for the Message.
    使用View许可改变在 `MessageBoard` 内容指令的需求陈述(42行)。让所有的留言用户都能访问描述和条目。改变64行。
  • Change the permission of line 46 to Edit, since only the message board administrator should be able to change any of the properties of the `MessageBoard` object.
  • All the container functionality will only require the view permission, so change the permission on line 68 to View. This is unsecure, since this includes read and write methods, but it will suffice for this demonstration.
  • For the Message we need to be able to set the attributes with the Add permission, so change line 72 to specify this permission.

Now let’s go to the browser configuration file ( messageboard/browser/configure.zcml) and fix the permissions there.

  • The permissions for the message board’s add form (line 11), add menu item (line 18), and its edit form (line 27) stay unchanged, since only an administrator should be able manage the board.
  • Since we want every user to see the messages in a messageboard, the permission on line 33 should become View. Since the contents view is meant for management, only principals with the Edit permission should be able to see it (line 34). Finally, you need the Add permission to actually add new messages to the message board (line 35). The same is true for the message’s container views permissions (line 84-86).
    由于我们想让每个用户都能看到留言簿里的留言,第33行上的许可应该是 View。因为内容视图意味着管理,只有编辑许可的主体才能看到它(34行)。最后,您需要添加消息到留言簿的添加许可(第35行)。这一样适用于消息容器视图查看许可(第84-86行)。
  • Since all user should be able to see the message thread and the message details, the permissions on line 43, 94, and 106 should become View.
  • On line 61 you should change the permission to Add, because you only allow messages to be added to the message board, if the user has this permission. The same is true for the message’s add menu item on line 68.
  • On line 78 make sure that a user can only access the edit screen if he has the Edit permission.

That’s it. If you would restart Zope 3 at this point, you could not even access the `MessageBoard` and/or Message instances. Therefore we need to create some roles next and assign permissions to them.
这就是我们想介绍给您的东西。如果您现在重启Zope 3 ,您将不能访问`MessageBoard` 和Message的实例。因为我们需要创建下一些角色并且分配许可给他们。

16.3 Step III: Declaration of Roles(16.3 步骤 III:声明角色)

The declaration of roles is specific to Zope 3’s default security policy. Another security policy might not even have the concept of roles at all. Therefore, the role declaration and grants to the permissions should not even be part of your package. For simplicity and keeping it all at one place, we are going to store the policy-specific security configuration in security.zcml. For our message board package we really only need two roles, “User” and “Editor”, which are declared as follows:
Zope 3 默认的安全策略才有角色的声明。 其它的安全策略甚至可能没有有角色这个概念。因此,角色声明和许可的授权不应该是您软件包的一部分。为了简单起见,我们把把它保存在一个地方,我们将在security.zcml文件中存储policy-specific安全配置。对于我们的留言簿软件包我们只需要两个角色,"User"和"Editor",如下:

1  <role
2      id="book.messageboard.User"
3      title="Message Board User"
4      description="Users that actually use the Message Board."/>
6  <role
7      id="book.messageboard.Editor"
8      title="Message Board Editor"
9      description="The Editor can edit and delete Messages."/>

Equivalently to the zope:permission directive, the zope:role directive creates and registers a new role with the global role registry. Again, the id must be a unique identifier that is used throughout the configuration process to identify the role. Both, the id and the title are required.
等价于zope:permission指令,zope:role指令以global role registry创建和注册了一个新的角色。在整个配置过程中,ID必须是一个区分角色独一无二的标识符。id和title(标题)都是必需的。

Next we grant the new permissions to the new roles, i.e. create a permission-role map. The user should be only to add and view messages, while the editor is allowed to execute all permission.
下一步我们授予新许可给新角色,i.e. 创建一个角色许可地图。当编辑器被允许执行所有许可的时候,用户应该只会添加和查看消息。

1  <grant
2      permission="book.messageboard.View"
3      role="book.messageboard.User"
4      />
5  <grant
6      permission="book.messageboard.Add"
7      role="book.messageboard.User"
8      />
9  <grant
10      permission="book.messageboard.Edit"
11      role="book.messageboard.Editor"
12      />
13  <grant
14      permission="book.messageboard.Delete"
15      role="book.messageboard.Editor"
16      />

The zope:grant directive is fairly complex, since it permits all three different types of security mappings. It allows you to assign a permission to a principal, a role to a principal, and a permission to a role. Therefore the directive has three optional arguments: permission, role, and principal. Exactly two of the three arguments have to be specified to make it a valid directive. All three security objects are specified by their id.
zope:grant指令是非常的复杂,因为它允许三种不同类型的安全映射。它允许您分配一个许可给一个主体,一个角色给一个主体,以及一个许可给一个角色。因此指令有三个选择参数:permission(许可)、 role(角色), 和principal(主体)。三个参数中的两个参数必须被指定,并且使它成为一个有效指令。三个安全对象通过它们的ID被指定。

Finally, you have to include the security.zcml file into your other configuration. This is simply done by adding the following inclusion directive in the ZOPE3/principals.zcml file。

1  <include package="book.messageboard" file="security.zcml" />

The reason we put it here is to make it obvious that this file depends on the security policy. Also, when assigning permissions to roles we want all possible permissions the system can have to be defined. Since the principals.zcml file is the last ZCML to be evaluated, this is the best place to put the declarations.

16.4 Step IV: Assigning Roles to Principals(16.4 步骤 IV:分配角色给主体)

To make our package work again, we now have to connect the roles to some principals. We are going to create two new principals called boarduser and boardeditor. To do that, go to the Zope 3 root directory and add the following lines to principals.zcml:
再次开始我们软件包的工作,我们现在必须把角色和一些主体连接起来。我们将创建两个名叫boarduser和boardeditor的新主体。为了做这些工作,到Zope 3根目录并且添加如下行到principals.zcml文件中:

1  <principal
2      id="book.messageboard.boarduser"
3      title="Message Board User"
4      login="boarduser" password="book"
5      />
6  <grant
7      role="book.messageboard.User"
8      principal="book.messageboard.boarduser"
9      />
11  <principal
12      id="book.messageboard.boardeditor"
13      title="Message Board Editor"
14      login="boardeditor" password="book"
15      />
16  <grant
17      role="book.messageboard.User"
18      principal="book.messageboard.boardeditor"
19      />
20  <grant
21      role="book.messageboard.Editor"
22      principal="book.messageboard.boardeditor"
23      />

The zope:principal directive creates and registers a new principal/user in the system. Like for all security object directives, the id and title attributes are required. We could also specify a description as well. In addition to these three attributes, the developer must specify a login and password (plain text) for the user, which is used for authentication of course.

Note that you might want to grant the book.messageboard.User role to the zope.anybody principal, so that everyone can view and add messages.
注意: 您可能想要授予book.messageboard.User角色给zope.anybody主体,以致于每个人都能查看和添加消息。

The zope.anybody principal is an unauthenticated principal, which is defined using the zope:unauthenticatedPrincipal directive, which has the same three basic attributes the zope:principal directive had, but does not accept the login and password attribute.
zope.anybody主体是一个未被认证的主体,使用 zope:unauthenticatedPrincipal 指令定义,有与zope:principal 指令相同的三个基本属性,但是不接受登陆(login)和密码(password)属性。

Now your system should be secure and usable. If you restart Zope 3 now, you will see that only the message board’s Editor can freely manipulate objects. (Of course you have to log in as one.)
现在您的系统应该是安全和可用的。如果您现在重启Zope 3 ,您将看见只有留言簿编辑者能自由地操纵对象。 (当然您必须以编辑者身份登录)。


      • In retrospect it was a bad idea to give the book.messageboard.User role the book.messageboard.View and book.messageboard.Add permission, since you cannot differentiate between an anonymous user reading the board and a user being able to add messages anymore. Add yet another role called book.messageboard.Viewer and make the details.html and thread.html view available to this role. Then grant this role to the unauthenticated principal ( anybody) and verify that this principal can indeed access these views.
        现在我们回过头来看,把book.messageboard.User 角色给book.messageboard.View 和book.messageboard.Add 的许可真的是一个很差的主意。因为您不能在匿名用户和能够添加消息的用户之间进行区分。添加另一个叫book.messageboard.Viewer 的角色并且使details.html和thread.html 的 view (查看)可用。然后把这个角色授予给没有认证的主体(任何人)并且修改这个主体能够真正地访问这些视图。
      • (Referring to the previous problem) On the other hand, instead of creating another role, we could just grant the View permission to the anonymous principal directly. Do that and ensure that the unauthenticated principal can see these views.