|
|
||||||||||||||||||
|
|
||||||||||||||||||
![]() |
![]() |
Version 1.0 / May 2, 2004
|
|||
|
SuperGuide Zope Security (Part I of III) - Users, Roles and Zope Security - - - - - - - - - - - - By Kristoph Kirchner| January 19, 2004 Introduction One of the Web's problems is that it is insecure by default - anyone with a browser and an Internet connection can view web pages. With some pages or sites this doesn't pose a problem because everyone is supposed to be able to view them. That's what the Web was designed for: it was meant for sharing knowledge. But it has evolved into much more than that. Nowadays the Internet is not just a place to obtain knowledge but to do business. And where business is concerned you need to implement security measures. Web applications, such as Content Management Systems (CMS) or online banking systems, need to implement security for either parts of websites or an entire site. Once you have created the security on paper, it has to be implemented. Often a lot of time is spent simply ensuring that the system is secure. Zope already comes with a security framework which goes a long way towards creating a secure web application: Zope does all the tedious work of checking authentication and authorization - once you've implemented your security policy for a site. Zope's Standard UserFolderZope comes with two standard UserFolders: the original standard UserFolder and one that was extended to allow for the creation of groups (note: this is not the same as roles – the difference will be explained below). In contrast to other Zope objects, Zope doesn't ask you for an id for the UserFolder since it is always automatically named acl_users. The "acl" stands for Access Control List. An access control list is a table that tells a computer operating system which access rights each user has to a particular system object, such as a file directory or an individual file (definition taken from http://whatis.techtarget.com. There can only be one acl_users object per folder in Zope. UserFolder automatically gives this name to the user folder when it is created and it cannot be changed. In a UserFolder you can add and delete users and edit them, as well – for example, to change a user's password. In Zope's original standard UserFolder, each user has a login name, password, domain restriction and role. (Note: the user's login name cannot be changed. If a mistake is made here the user has to be erased and a new user object created.) If the domain restriction is empty, the user can access Zope from any domain. You can restrict that access so that a user can only log in to Zope from, for example, the domain mycompany.com. Domains can also be entered as IP addresses with asterisks, e.g. 222.11.33.*. Access for a user is restricted to the folder containing the UserFolder (or UserFolders) he is defined in, as well as its sub-objects. The other type of UserFolder that now comes with Zope allows you to create groups. As the name suggests, with this UserFolder you can group users together, for example to define departments in a company. Groups have no impact on the standard authentication and authorization process. Roles group permissions together, while groups are used to bring users together. This allows for greater flexibility. A user can have one or more roles to define the actions (=permissions) he is allowed to perform in regard to the objects on a Zope site, and he can belong to one or more groups which categorize him, putting him together with other users who don't necessarily have the same role(s) (and therefore the same permissions) he does. Acquisition and SecurityZope's acquisition is a powerful feature which makes life much easier for developers and webmasters since part of acquisition is that objects automatically acquire their parent object's attributes (for example, the security policy defined for the parent object) if the object's attributes are not explicitly defined. As just mentioned, acquisition also applies to security policies. A policy defined in a folder will apply to itself and its sub-objects. If a user tries to access an object, Zope checks whether there is a security policy defined for the object. If there isn't, it then looks up the security policy for the containing object. If that object also doesn't have a policy assigned to it, Zope goes up another level and so on up a sequence of nested objects until one reaches the root folder. This is a potent feature because you can set one policy in the top-most folder, the root folder, and this policy will automatically apply to all objects in your Zope site, if it isn't deliberately interrupted somewhere (if it is interrupted, then that interruption is valid for all sub-objects from that point on). Once you have defined the security policy for the root folder (or accepted the default one), you can then refine security for different sub-objects by interrupting the chain of acquisition. The Security tab of an object shows all permissions that can be mapped to roles for a given object. For each permission you can interrupt the chain of acquisition by deactivating the checkbox 'Acquire permission setting?' in front of it. When this is done you can select which roles shall have this permission for this specific object and its sub-objects, if it has any. Proxy RolesSometimes you create objects you want to be accessible to users no matter what their role is. One such object, for example, could be a DTML Method that uses the sendmail-tag and takes the data that a user has entered into a feedback form and sends it to an administrator. In order for a user to call this DTML Method, he would need to have the permission to use the MailHost object. However, since granting a user the permission to use to the MailHost object runs the risk of his using it to send private emails, you wouldn't want to give this permission to the Anonymous role. In this case, you can assign the object a proxy role – i.e., you can assign it a role which does have the permission to use the MailHost. If, for example, an anonymous user then tries to access this DTML Method, Zope doesn't care that the user actually isn't allowed to use the MailHost since the DTML Method is allowed to do it over the proxy role. When setting Proxy roles, keep in mind that you need to have the Manager role in order to assign the Manager role as a Proxy role. Local RolesLocal roles are an easy way to grant a user permissions for a specific object, in addition to the permissions he already has over a role (or over roles) defined elsewhere on the Zope site. They are set for an object and define that for this object a specific user has a certain role. Let's say you defined the user Joe with the role Member in the root of your Zope site and that the Member role only allows a user to view objects – i.e. you have defined the role Member in this way. However, you have decided to give Joe more permissions in one subfolder, e.g. the folder News. For this one folder, you want him to have the additional permissions to add and edit objects. Let's say you defined another role called Editor that has these permissions. You can then give Joe the local role of Editor for the folder News, granting him the additional permissions to add and edit objects in this particular folder. In any other folder and in the root folder itself, Joe will still only be able to view objects and not to add or edit them. Note: to grant Joe these extra permissions you would have to interrupt the chain of acquisition at this folder (since Joe doesn't have the right to add and edit objects anywhere else). Further, if News had sub-objects in which Joe was not to have these permissions, one would have to break the chain of acquisition for these sub-objects and re-establish Joe's original security settings. Zope's Security FrameworkZope's in-built security framework has been overhauled and improved several times to enable the programmer to build securer applications. In Zope, access to an object is granted after two checks have been passed:
Authentication is the process of identifying a user to make certain he is who is says he is. If a user tries to access a protected object, Zope asks for a username and password, i.e. the user has to log in to Zope. (Up to this point he has had the role Anonymous with its minimal default permissions, or whatever permissions the programmer has defined for this role). Zope checks whether the user exists in the current context and whether the stored password matches the one that was entered. Authorization is the process of finding out what this user is allowed to do in the current context. Once the user is logged in, Zope checks whether he has the correct permissions to perform the desired action on the object he attempted to access (the action that triggered the authentication call) – for example, whether he has the permission to view it. Therefore, authorization depends on a user's permissions for an object. Permissions define actions, such as viewing an object or deleting it. Zope has various predefined permissions which are associated with different actions. You can see these permissions in the Security tab of an object. You will see that Folder objects have many more permissions defined for them than, for example, Page Template objects. This is because there are many more actions you can perform on or within a Folder that you cannot perform on a simple (i.e. non-folderish) object, such as adding new objects to it or copying and pasting objects into it. In order to create your security structure in Zope, you first define security policies. Security policies are used to map permissions to roles, i.e. to define who is allowed to do what with a specific object. Roles, such as Manager and Anonymous, define classes of users that have the same permissions,. In a new Zope server, four roles are defined by default (note: the permissions automatically assigned to these roles can be changed):
The Anonymous role is assigned to anyone who accesses a Zope object but has not logged in yet. So, this role must have enough permissions to enable a user to access public pages in your Web application. More specifically: for an object to be public, the Anonymous role must have certain permissions for this specific object, since anyone trying to access the object will automatically be assigned the role Anonymous. (Note: This assignation is transparent to the user: he doesn't see that he's been assigned this role or what permissions have been defined for it. His only awareness of there's being a security structure defined for the Zope site is when he is asked to log in or is denied access to an object.) We'll talk more about permissions later. The Authenticated role is, in a sense, the opposite of the Anonymous role. Once a user has logged in to Zope he is automatically assigned this role. The Anonymous role is assigned to a user unknown to the Zope site; the Authenticated role is assigned to a user known to the Zope site (i.e., who has correctly identified himself to the Zope site by logging in). By default, the Manager role has every permission there is. A user with this role is allowed to do anything that is possible in Zope. Note that it is potentially dangerous to play around with the permissions for the Manager role because you could lock yourself out of part of your site or even the whole site. In the worst case, if you make an unfortunate change of permissions in the root folder, you will have to reinstall your Zope server (losing thereby all your data, if you haven't made a backup of the Zope server). It is a good policy to perform tests in a test sub-folder so that if anything goes wrong you can erase that folder and still keep the Zope server. The Owner role was introduced to avoid a particular security risk (see next paragraph for details). It is not supposed to be used as an actual role for a user but is used by Zope to identify the "owner" of an object. This is important when several people have access to your Zope site. When an object is created, the user creating it is automatically set as the owner of the object; however, users that have the correct permission (for example, a user with the role Manager) can take ownership of an object from another user. It is not possible for a user to assign ownership of an object to someone other than himself (i.e., there is no such permission in Zope). Before the category ownership was defined for Zope, a user could create a Python script with harmful code even though he might not have had the right permissions to actually view (i.e. execute) it. If he then was able to trick someone with the correct permissions into viewing it the harmful code would have been carried out. With the introduction of the Owner role this is no longer possible. For example, say there is a command in the Python code to delete all files on the Zope site, a permission its programmer doesn't have, but which the second user does have. Before ownership was introduced the code would have been carried out if the second user viewed it and all files deleted. Now Zope recognizes that the owner of the Python code is a user without the permission to delete files and will refuse to carry out the code, despite the fact that the second user does have this permission. Authorization has taken on a new layer: objects can only be viewed (executed) if both the user attempting to view it as well as the owner of the object have the appropriate permissions. The authentication and authorization process is triggered whenever a user tries to access a protected object, i.e. an object that the current user does not have sufficient permissions to access. The user would then have to enter a username associated with a role that does have the requisite permission(s). Alternative UserFoldersZope's standard UserFolder only lets you save basic user data, i.e. data that is absolutely necessary for the authentication and authorization process. Maybe that is enough for what you want to do with Zope, but maybe it's not. There are several reasons why you might not want to use Zope's standard UserFolder:
You could write your own UserFolder product in Python and implement all the features you require. But there's already a large number of products available, written by people in the Zope community. The section User Management of the "Products" sectioon on zope.org contains various alternatives to the standard Zope UserFolder which, for example, address the problems mentioned above. There are several UserFolder products that bridge the gap between Zope and a relational database, e.g. mySQL or postgreSQL. You can even have users authenticated against an LDAP server or their Windows NT domain credentials. There is also a list of UserFolder products that address user groups, such as the NuxUserGroups product or the GroupUserFolder product. Security in Unrestricted CodeThere are two types of code in Zope: restricted and unrestricted. So far we've only talked about restricted code, i.e. the code used inside the ZODB which is editable through the Web (TTW). The code that can be used inside the ZODB, e.g. in Python Scripts, is restricted to prevent users from creating potentially harmful code. Code outside the ZODB, i.e. code in the filesystem in Python modules, is unrestricted and therefore needs special care. "Unrestricted" means you can do anything that Python allows you to do. When writing new Zope products or External Methods that will be called from the ZODB, you need to restrict access to the methods manually because this code is not governed by the security policy you create for objects inside the ZODB. To define security for unrestricted code you use SecurityInfo objects. For a Python class, for example, you create a ClassSecurityInfo object which will contain the security information for the various methods inside the class, as well as for the class itself. Using this security object, you can then define whether a specific class method is:
Security of unrestricted code in earlier versions of Zope was implicit: this assumed that everything was accessible from the ZODB and the programmer had to specificly define protected objects or code. As of Zope 2.2 this policy has changed: security of unrestricted code has become explicit, which means that objects must have a security policy defined for them in order to be accessible. By default, since Python code you write does not have a security status, as of Zope 2.2 it cannot be accessed until you've explicitly defined security for it. This concludes the introductory part of our SuperGuide on Zope Security. In the next part of this SuperGuide we will go more deeply into defining security policies for unrestricted code and give some examples. Related ZopeMag Links of interest:Customized UserFolders Part I, II and III: http://www.zopemag.com/Issue001/Section_Tutorials/tutorial_UserFolders_01.htmlhttp://www.zopemag.com/Issue002/Section_Articles/article_cuf2_01.html http://www.zopemag.com/Issue006/Section_Articles/article_CustomizedUserFolders.html Building a Community Site - Step by Step: http://www.zopemag.com/Issue003/Section_Articles/article_PracticalSolutions.htmlhttp://www.zopemag.com/Issue005/Section_Articles/article_snippets2.html Transactions by example: An Online Registration Desk with Zope and PostgreSQL (Part I and II) http://www.zopemag.com/Issue003/Section_Articles/article_PostgresTransactionsPartI.htmlhttp://www.zopemag.com/Issue004/Section_Articles/article_PostgresTransactionsPartII.html |
|||||||||||||||||||||||||||||||||||||||||||||||||
| ZopeMag is committed to bringing you the best in Zope Documentation. | ||||||||||||||||||||||||||||||||||||||||||||||||||
![]() |
Reproduction of material from any of ZopeMag's pages without prior written permission is strictly prohibited. Copyright 2003 - 2005 ZopeMag |
|