ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 02.01.2026

Просмотров: 2722

Скачиваний: 0

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

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


CHAPTER

TWENTYEIGHT

COMBINING TRAVERSAL AND URL DISPATCH

When you write most Pyramid applications, you’ll be using one or the other of two available resource location subsystems: traversal or URL dispatch. However, to solve a limited set of problems, it’s useful to use both traversal and URL dispatch together within the same application. Pyramid makes this possible via hybrid applications.

latex-warning.png

Reasoning about the behavior of a “hybrid” URL dispatch + traversal application can be challenging. To successfully reason about using URL dispatch and traversal together, you need to understand URL pattern matching, root factories, and the traversal algorithm, and the potential interactions between them. Therefore, we don’t recommend creating an application that relies on hybrid behavior unless you must.

28.1 A Review of Non-Hybrid Applications

When used according to the tutorials in its documentation Pyramid is a “dual-mode” framework: the tutorials explain how to create an application in terms of using either url dispatch or traversal. This chapter details how you might combine these two dispatch mechanisms, but we’ll review how they work in isolation before trying to combine them.

305

28. COMBINING TRAVERSAL AND URL DISPATCH

28.1.1 URL Dispatch Only

An application that uses url dispatch exclusively to map URLs to code will often have statements like this within application startup configuration:

1 # config is an instance of pyramid.config.Configurator

2

3 config.add_route(’foobar’, ’{foo}/{bar}’) 4 config.add_route(’bazbuz’, ’{baz}/{buz}’)

5

6 config.add_view(’myproject.views.foobar’, route_name=’foobar’) 7 config.add_view(’myproject.views.bazbuz’, route_name=’bazbuz’)

Each route corresponds to one or more view callables. Each view callable is associated with a route by passing a route_name parameter that matches its name during a call to add_view(). When a route is matched during a request, view lookup is used to match the request to its associated view callable. The presence of calls to add_route() signify that an application is using URL dispatch.

28.1.2 Traversal Only

An application that uses only traversal will have view configuration declarations that look like this:

1# config is an instance of pyramid.config.Configurator

2

3config.add_view(’mypackage.views.foobar’, name=’foobar’)

4config.add_view(’mypackage.views.bazbuz’, name=’bazbuz’)

When the above configuration is applied to an application, the mypackage.views.foobar view callable above will be called when the URL /foobar is visited. Likewise, the view mypackage.views.bazbuz will be called when the URL /bazbuz is visited.

Typically, an application that uses traversal exclusively won’t perform any calls to pyramid.config.Configurator.add_route() in its startup code.

306