zope.authentication README

Latest release Supported Python versions https://travis-ci.org/zopefoundation/zope.authentication.png?branch=master https://coveralls.io/repos/github/zopefoundation/zope.authentication/badge.svg?branch=master Documentation Status

This package provides a definition of authentication concepts for use in Zope Framework. This includes:

  • IAuthentication
  • IUnauthenticatedPrincipal
  • ILogout

Documentation is hosted at https://zopeauthentication.readthedocs.io/en/latest/

Contents:

Logout Support

Logout support is defined by a simple interface zope.authentication.interfaces.ILogout:

>>> from zope.authentication.interfaces import ILogout

that has a single ‘logout’ method.

The current use of ILogout is to adapt an zope.authentication.interfaces.IAuthentication instance to ILogout. To illustrate, we’ll create a simple logout implementation that adapts IAuthentication:

>>> from zope.component import adapter, provideAdapter
>>> from zope.interface import implementer
>>> from zope.authentication.interfaces import IAuthentication
>>> @adapter(IAuthentication)
... @implementer(ILogout)
... class SimpleLogout(object):
...
...     def __init__(self, auth):
...         pass
...
...     def logout(self, request):
...         print('User has logged out')

>>> provideAdapter(SimpleLogout)

and something to represent an authentication utility:

>>> @implementer(IAuthentication)
... class Authentication(object):
...     pass

>>> auth = Authentication()

To perform a logout, we adapt auth to ILogout and call ‘logout’:

>>> logout = ILogout(auth)
>>> request = object()
>>> logout.logout(request)
User has logged out

The ‘NoLogout’ Adapter

The zope.authentication.logout.NoLogout class can be registered as a fallback provider of ILogout for IAuthentication components that are not otherwise adaptable to ILogout. NoLogout‘s logout method is a no-op.

>>> from zope.authentication.logout import NoLogout
>>> NoLogout(auth).logout(request)

Logout User Interface

Because some authentication protocols do not formally support logout, it may not be possible for a user to logout once he or she has logged in. In such cases, it would be inappropriate to present a user interface for logging out.

Because logout support is site-configurable, Zope provides an adapter that, when registered, indicates that the site is configured for logout. This class merely serves as a flag as it implements ILogoutSupported:

>>> from zope.authentication.logout import LogoutSupported
>>> from zope.authentication.interfaces import ILogoutSupported
>>> ILogoutSupported.implementedBy(LogoutSupported)
True
>>> ILogoutSupported.providedBy(LogoutSupported(request))
True

Principal Terms

Principal Terms are used to support browser interfaces for searching principal sources. They provide access to tokens and titles for values. The principal terms view uses an authentication utility to get principal titles. Let’s create an authentication utility to demonstrate how this works:

>>> class Principal(object):
...     def __init__(self, id, title):
...         self.id, self.title = id, title

>>> from zope.interface import implementer
>>> from zope.authentication.interfaces import IAuthentication
>>> from zope.authentication.interfaces import PrincipalLookupError
>>> @implementer(IAuthentication)
... class AuthUtility:
...     data = {'jim': 'Jim Fulton', 'stephan': 'Stephan Richter'}
...
...     def getPrincipal(self, id):
...         title = self.data.get(id)
...         if title is not None:
...             return Principal(id, title)
...         raise PrincipalLookupError

Now we need to install the authentication utility:

>>> from zope.component import provideUtility
>>> provideUtility(AuthUtility(), IAuthentication)

We need a principal source so that we can create a view from it.

>>> from zope.component import getUtility
>>> class PrincipalSource(object):
...     def __contains__(self, id):
...          auth = getUtility(IAuthentication)
...          try:
...              auth.getPrincipal(id)
...          except PrincipalLookupError:
...              return False
...          else:
...              return True

Now we can create an terms view and ask the terms view for terms:

>>> from zope.authentication.principal import PrincipalTerms
>>> terms = PrincipalTerms(PrincipalSource(), None)
>>> term = terms.getTerm('stephan')
>>> term.title
'Stephan Richter'
>>> term.token
u'c3RlcGhhbg__'

If we ask for a term that does not exist, we get a lookup error:

>>> terms.getTerm('bob')
Traceback (most recent call last):
...
LookupError: bob

If we have a token, we can get the principal id for it.

>>> terms.getValue('c3RlcGhhbg__')
u'stephan'

API Reference

Interfaces

Authentication interfaces

exception zope.authentication.interfaces.PrincipalLookupError[source]

Bases: exceptions.LookupError

No principal for given principal id

interface zope.authentication.interfaces.IUnauthenticatedPrincipal[source]

Extends: zope.security.interfaces.IPrincipal

A principal that hasn’t been authenticated.

Authenticated principals are preferable to UnauthenticatedPrincipals.

interface zope.authentication.interfaces.IFallbackUnauthenticatedPrincipal[source]

Extends: zope.authentication.interfaces.IUnauthenticatedPrincipal

Marker interface for the fallback unauthenticated principal.

This principal can be used by publications to set on a request if no principal, not even an unauthenticated principal, was returned by any authentication utility to fulfill the contract of IApplicationRequest.

interface zope.authentication.interfaces.IUnauthenticatedGroup[source]

Extends: zope.security.interfaces.IGroup

A group containing unauthenticated users

interface zope.authentication.interfaces.IAuthenticatedGroup[source]

Extends: zope.security.interfaces.IGroup

A group containing authenticated users

interface zope.authentication.interfaces.IEveryoneGroup[source]

Extends: zope.security.interfaces.IGroup

A group containing all users

interface zope.authentication.interfaces.IAuthentication[source]

Provide support for establishing principals for requests.

This is implemented by performing protocol-specific actions, such as issuing challenges or providing login interfaces.

IAuthentication objects are used to implement authentication utilities. Because they implement utilities, they are expected to collaborate with utilities in other contexts. Client code doesn’t search a context and call multiple utilities. Instead, client code will call the most specific utility in a place and rely on the utility to delegate to other utilities as necessary.

The interface doesn’t include methods for data management. Utilities may use external data and not allow management in Zope. Simularly, the data to be managed may vary with different implementations of a utility.

authenticate(request)

Identify a principal for a request.

If a principal can be identified, then return the principal. Otherwise, return None.

The request object is fairly opaque. We may decide that it implements some generic request interface.

Note

Implementation note: It is likely that the component will dispatch to another component based on the actual request interface. This will allow different kinds of requests to be handled correctly.

For example, a component that authenticates based on user names and passwords might request an adapter for the request as in:

getpw = getAdapter(request, context=self)

The context keyword argument is used to control where the ILoginPassword component is searched for. This is necessary because requests are placeless.

unauthenticatedPrincipal()

Return the unauthenticated principal, if one is defined.

Return None if no unauthenticated principal is defined.

The unauthenticated principal must provide IUnauthenticatedPrincipal.

unauthorized(id, request)

Signal an authorization failure.

This method is called when an auhorization problem occurs. It can perform a variety of actions, such as issuing an HTTP authentication challenge or displaying a login interface.

Note that the authentication utility nearest to the requested resource is called. It is up to authentication utility implementations to collaborate with utilities higher in the object hierarchy.

If no principal has been identified, id will be None.

getPrincipal(id)

Get principal meta-data.

Returns an object of type IPrincipal for the given principal id. A PrincipalLookupError is raised if the principal cannot be found.

Note that the authentication utility nearest to the requested resource is called. It is up to authentication utility implementations to collaborate with utilities higher in the object hierarchy.

interface zope.authentication.interfaces.ILoginPassword[source]

A password based login.

An IAuthentication utility may use this (adapting a request), to discover the login/password passed from the user, or to indicate that a login is required.

getLogin()

Return login name, or None if no login name found.

getPassword()

Return password, or None if no login name found.

If there’s a login but no password, return empty string.

needLogin(realm)

Indicate that a login is needed.

The realm argument is the name of the principal registry.

interface zope.authentication.interfaces.IPrincipalSource[source]

Extends: zope.schema.interfaces.ISource

A Source of Principal Ids

interface zope.authentication.interfaces.ILogout[source]

Provides support for logging out.

logout(request)

Perform a logout.

interface zope.authentication.interfaces.ILogoutSupported[source]

A marker indicating that the security configuration supports logout.

Provide an adapter to this interface to signal that the security system supports logout.

Principals

Principal source and helper function

zope.authentication.principal.checkPrincipal(context, principal_id)[source]

An utility function to check if there’s a principal for given principal id.

Raises ValueError when principal doesn’t exists for given context and principal id.

To test it, let’s create and register a dummy authentication utility.

>>> from zope.authentication.interfaces import IAuthentication
>>> from zope.authentication.interfaces import PrincipalLookupError
>>> from zope.interface import implementer
>>> @implementer(IAuthentication)
... class DummyUtility(object):
...
...     def getPrincipal(self, id):
...         if id == 'bob':
...             return id
...         raise PrincipalLookupError(id)
>>> from zope.component import provideUtility
>>> provideUtility(DummyUtility())

Now, let’s check the behaviour of this function.

>>> from zope.authentication.principal import checkPrincipal
>>> checkPrincipal(None, 'bob')
>>> checkPrincipal(None, 'dan')
Traceback (most recent call last):
...
ValueError: ('Undefined principal id', 'dan')
class zope.authentication.principal.PrincipalSource[source]

Bases: object

Generic Principal Source

Implements zope.authentication.interfaces.IPrincipalSource and zope.schema.interfaces.ISourceQueriables.

__contains__(id)[source]

Test for the existence of a user.

We want to check whether the system knows about a particular principal, which is referenced via its id. The source will go through the most local authentication utility to look for the principal. Whether the utility consults other utilities to give an answer is up to the utility itself.

First we need to create a dummy utility that will return a user, if the id is ‘bob’.

>>> from zope.authentication.interfaces import IAuthentication
>>> from zope.interface import implementer
>>> @implementer(IAuthentication)
... class DummyUtility(object):
...     def getPrincipal(self, id):
...         if id == 'bob':
...             return id
...         raise PrincipalLookupError(id)

Let’s register our dummy auth utility.

>>> from zope.component import provideUtility
>>> provideUtility(DummyUtility())

Now initialize the principal source and test the method

>>> from zope.authentication.principal import PrincipalSource
>>> source = PrincipalSource()
>>> 'jim' in source
False
>>> 'bob' in source
True
getQueriables()[source]

Returns an iteratable of queriables.

Queriables are responsible for providing interfaces to search for principals by a set of given parameters (can be different for the various queriables). This method will walk up through all of the authentication utilities to look for queriables.

>>> from zope.schema.interfaces import ISourceQueriables
>>> @implementer(IAuthentication)
... class DummyUtility1(object):
...     __parent__ = None
...     def __repr__(self): return 'dummy1'
>>> dummy1 = DummyUtility1()
>>> @implementer(ISourceQueriables, IAuthentication)
... class DummyUtility2(object):
...     __parent__ = None
...     def getQueriables(self):
...         return ('1', 1), ('2', 2), ('3', 3)
>>> dummy2 = DummyUtility2()
>>> @implementer(IAuthentication)
... class DummyUtility3(DummyUtility2):
...     def getQueriables(self):
...         return ('4', 4),
>>> dummy3 = DummyUtility3()
>>> from zope.authentication.tests.utils import testingNextUtility
>>> testingNextUtility(dummy1, dummy2, IAuthentication)
>>> testingNextUtility(dummy2, dummy3, IAuthentication)
>>> from zope.component import provideUtility
>>> provideUtility(dummy1)
>>> from zope.authentication.principal import PrincipalSource
>>> source = PrincipalSource()
>>> list(source.getQueriables())
[(u'0', dummy1), (u'1.1', 1), (u'1.2', 2), (u'1.3', 3), (u'2.4', 4)]
class zope.authentication.principal.PrincipalTerms(context, request)[source]

Bases: object

Implementation of zope.browser.interfaces.ITerms given a zope.authentication.interfaces.IPrincipalSource and request object.

getTerm(principal_id)[source]

Return a PrincipalTerm for the given ID.

If no such principal can be found, raises LooupError.

getValue(token)[source]

Return the principal ID given its token.

class zope.authentication.principal.PrincipalTerm(token, title)[source]

Bases: object

A principal term.

We have a token based on the encoded principal ID, and a title.

Login

Login/Password provider.

class zope.authentication.loginpassword.LoginPassword(login, password)[source]

Bases: object

Basic zope.authentication.interfaces.ILoginPassword implementation.

This class can be used as a base for implementing ILoginPassword adapters.

Logout

ILogout implementations

class zope.authentication.logout.NoLogout(auth)[source]

Bases: object

An adapter for IAuthentication utilities that don’t implement ILogout.

logout(request)[source]

Does nothing.

class zope.authentication.logout.LogoutSupported(dummy)[source]

Bases: object

A class that can be registered as an adapter to flag logout support.

Changes

4.4.0 (unreleased)

4.3.0 (2017-05-11)

  • Add support for Python 3.5 and 3.6.
  • Drop support for Python 2.6 and 3.2.

4.2.1 (2015-06-05)

  • Add support for PyPy3 and Python 3.2.

4.2.0 (2014-12-26)

4.1.0 (2013-02-21)

  • Add support for Python 3.3.
  • Add tox.ini and MANIFEST.in.

4.0.0 (2012-07-04)

  • Break inappropriate testing dependency on zope.component.nextutility.

    (Forward-compatibility with zope.component 4.0.0).

  • Replace deprecated zope.component.adapts usage with equivalent zope.component.adapter decorator.

  • Replace deprecated zope.interface.implements usage with equivalent zope.interface.implementer decorator.

  • Drop support for Python 2.4 and 2.5.

3.7.1 (2010-04-30)

  • Remove undeclared testing dependency on zope.testing.

3.7.0 (2009-03-14)

Initial release. This package was split off from zope.app.security to provide a separate common interface definition for authentication utilities without extra dependencies.

Development

zope.authentication is hosted at GitHub:

Project URLs

Indices and tables