Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
pyramid.pdf
Скачиваний:
10
Добавлен:
24.03.2015
Размер:
3.82 Mб
Скачать

27. SECURITY

27.6 Special Permissions

Special permission names exist in the pyramid.security module. These can be imported for use in ACLs. pyramid.security.ALL_PERMISSIONS

An object representing, literally, all permissions. Useful in an ACL like so: (Allow, ’fred’, ALL_PERMISSIONS). The ALL_PERMISSIONS object is actually a stand-in object that has a __contains__ method that always returns True, which, for all known authorization policies, has the effect of indicating that a given principal “has” any permission asked for by the system.

27.7 Special ACEs

A convenience ACE is defined representing a deny to everyone of all permissions in pyramid.security.DENY_ALL. This ACE is often used as the last ACE of an ACL to explicitly cause inheriting authorization policies to “stop looking up the traversal tree” (effectively breaking any inheritance). For example, an ACL which allows only fred the view permission for a particular resource despite what inherited ACLs may say when the default authorization policy is in effect might look like so:

1

2

3

4

from pyramid.security import Allow from pyramid.security import DENY_ALL

__acl__ = [ (Allow, ’fred’, ’view’), DENY_ALL ]

“Under the hood”, the pyramid.security.DENY_ALL ACE equals the following:

1

2

from pyramid.security import ALL_PERMISSIONS __acl__ = [ (Deny, Everyone, ALL_PERMISSIONS) ]

27.8 ACL Inheritance and Location-Awareness

While the default authorization policy is in place, if a resource object does not have an ACL when it is the context, its parent is consulted for an ACL. If that object does not have an ACL, its parent is consulted for an ACL, ad infinitum, until we’ve reached the root and there are no more parents left.

In order to allow the security machinery to perform ACL inheritance, resource objects must provide location-awareness. Providing location-awareness means two things: the root object in the resource tree must have a __name__ attribute and a __parent__ attribute.

300

27.9. CHANGING THE FORBIDDEN VIEW

1 class Blog(object):

2__name__ = ’’

3__parent__ = None

An object with a __parent__ attribute and a __name__ attribute is said to be location-aware. Location-aware objects define an __parent__ attribute which points at their parent object. The root object’s __parent__ is None.

See pyramid.location for documentations of functions which use location-awareness. See also LocationAware Resources.

27.9 Changing the Forbidden View

When Pyramid denies a view invocation due to an authorization denial, the special forbidden view is invoked. “Out of the box”, this forbidden view is very plain. See Changing the Forbidden View within Using Hooks for instructions on how to create a custom forbidden view and arrange for it to be called when view authorization is denied.

27.10 Debugging View Authorization Failures

If your application in your judgment is allowing or denying view access inappropriately, start your application under a shell using the PYRAMID_DEBUG_AUTHORIZATION environment variable set to 1. For example:

$ PYRAMID_DEBUG_AUTHORIZATION=1 bin/pserve myproject.ini

When any authorization takes place during a top-level view rendering, a message will be logged to the console (to stderr) about what ACE in which ACL permitted or denied the authorization based on authentication information.

This behavior can also be turned on in the application .ini file by setting the pyramid.debug_authorization key to true within the application’s configuration section, e.g.:

1

2

3

[app:main]

use = egg:MyProject pyramid.debug_authorization = true

With this debug flag turned on, the response sent to the browser will also contain security debugging information in its body.

301

27. SECURITY

27.11 Debugging Imperative Authorization Failures

The pyramid.security.has_permission() API

is used to check security within

view

functions

imperatively.

It

returns

instances of

objects that are effectively booleans.

But these objects are not

raw

True

or

False

objects,

and have

information

at-

tached to

them

about why

the

permission

was allowed or

denied.

The object

will

be

one

of

pyramid.security.ACLAllowed,

pyramid.security.ACLDenied,

pyramid.security.Allowed, or pyramid.security.Denied, as documented in pyramid.security. At the very minimum these objects will have a msg attribute, which is a string indicating why the permission was denied or allowed. Introspecting this information in the debugger or via print statements when a call to has_permission() fails is often useful.

27.12 Creating Your Own Authentication Policy

Pyramid ships with a number of useful out-of-the-box security policies (see pyramid.authentication). However, creating your own authentication policy is often necessary when you want to control the “horizontal and vertical” of how your users authenticate. Doing so is a matter of creating an instance of something that implements the following interface:

1 class IAuthenticationPolicy(object):

2""" An object representing a Pyramid authentication policy. """

3

4def authenticated_userid(self, request):

5""" Return the authenticated userid or ‘‘None‘‘ if no

6authenticated userid can be found. This method of the policy

7 should ensure that a record exists in whatever persistent store is 8 used related to the user (the user should not have been deleted); 9 if a record associated with the current id does not exist in a

10 persistent store, it should return ‘‘None‘‘."""

11

12def unauthenticated_userid(self, request):

13""" Return the *unauthenticated* userid. This method performs the

14same duty as ‘‘authenticated_userid‘‘ but is permitted to return the

15userid based only on data present in the request; it needn’t (and

16shouldn’t) check any persistent store to ensure that the user record

17related to the request userid exists."""

18

19def effective_principals(self, request):

20""" Return a sequence representing the effective principals

21including the userid and any groups belonged to by the current

22user, including ’system’ groups such as

302

27.13. CREATING YOUR OWN AUTHORIZATION POLICY

23‘‘pyramid.security.Everyone‘‘ and

24‘‘pyramid.security.Authenticated‘‘. """

25

26def remember(self, request, principal, **kw):

27""" Return a set of headers suitable for ’remembering’ the

28principal named ‘‘principal‘‘ when set in a response. An

29individual authentication policy and its consumers can decide

30on the composition and meaning of **kw. """

31

32def forget(self, request):

33""" Return a set of headers suitable for ’forgetting’ the

34current user on subsequent requests. """

After you do so, you can pass an instance of such a class into the set_authentication_policy method configuration time to use it.

27.13 Creating Your Own Authorization Policy

An

authorization

policy is

a policy

that allows or

denies

access

after a

user

has been

authenticated.

Most

Pyramid applications

will

use the

default

pyramid.authorization.ACLAuthorizationPolicy.

However, in some cases, it’s useful to be able to use a different authorization policy than the default ACLAuthorizationPolicy. For example, it might be desirable to construct an alternate authorization policy which allows the application to use an authorization mechanism that does not involve ACL objects.

Pyramid ships with only a single default authorization policy, so you’ll need to create your own if you’d like to use a different one. Creating and using your own authorization policy is a matter of creating an instance of an object that implements the following interface:

1 class IAuthorizationPolicy(object):

2 """ An object representing a Pyramid authorization policy. """

3def permits(self, context, principals, permission):

4""" Return ‘‘True‘‘ if any of the ‘‘principals‘‘ is allowed the

5‘‘permission‘‘ in the current ‘‘context‘‘, else return ‘‘False‘‘

6"""

7

8def principals_allowed_by_permission(self, context, permission):

9""" Return a set of principal identifiers allowed by the

10 ‘‘permission‘‘ in ‘‘context‘‘. This behavior is optional; if you

303

27. SECURITY

11choose to not implement it you should define this method as

12something which raises a ‘‘NotImplementedError‘‘. This method

13will only be called when the

14‘‘pyramid.security.principals_allowed_by_permission‘‘ API is

15used."""

After you do so, you can pass an instance of such a class into the set_authorization_policy method at configuration time to use it.

304

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]