:mod:`repoze.who` Use Cases
|
===========================
|
|
How should an application interact with :mod:`repoze.who`? There are three
|
main scenarios:
|
|
Middleware-Only Use Cases
|
-------------------------
|
|
Examples of using the :mod:`repoze.who` middleware, without explicitly
|
using its API.
|
|
|
Simple: Bug Tracker with ``REMOTE_USER``
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
This application expects the ``REMOTE_USER`` variable to be set by
|
the middleware for authenticated requests. It allows the middleware to
|
handle challenging the user when needed.
|
|
In protected views, such as those which allow creating or following up
|
to bug reports:
|
|
- Check ``environ['REMOTE_USER']`` to get the authenticated user, and apply
|
any application-specific policy (who is allowed to edit).
|
|
- If the access check fails because the user is not yet authenticated,
|
return an 401 Unauthorized response.
|
|
- If the access check fails for authenticated users, return a
|
403 Forbidden response.
|
|
Note that the application here doesn't depend on :mod:`repoze.who` at
|
all: it would work identically if run behind Apache's ``mod_auth``. The
|
``Trac`` application works exactly this way.
|
|
The middleware can be configured to suit the policy required for the
|
site, e.g.:
|
|
- challenge / identify using HTTP basic authentication
|
|
- authorize via an ``.htaccces``-style file.
|
|
|
More complex: Wiki with ``repoze.who.identity``
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
This application use the ``repoze.who.identity`` variable set in the
|
WSGI environment by the middleware for authenticated requests. The application
|
still allows the middleware to handle challenging the user when needed.
|
|
The only difference from the previous example is that protected views,
|
such as those which allow adding or editing wiki pages, can use the extra
|
metadata stored inside ``environ['repoze.who.identity']`` (a mapping) to
|
make authorization decisions: such metadata might include groups or roles
|
mapped by the middleware onto the user.
|
|
|
API-Only Use Cases
|
------------------
|
|
Examples of using the :mod:`repoze.who` API without its middleware.
|
|
|
Simple: Wiki with its own login and logout views.
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
This application uses the :mod:`repoze.who` API to compute the authenticated
|
user, as well as using its ``remember`` API to set headers for cookie-based
|
authentication.
|
|
In each view:
|
|
- Call ``api.authenticate`` to get the authenticated user.
|
|
- Show a ``login`` link for non-authenticated requests.
|
|
- Show a ``logout`` link for authenticated requests.
|
|
- Don't show "protected" links for non-authenticated requests.
|
|
In protected views, such as those which allow adding or editing
|
wiki pages:
|
|
- Call ``api.authenticate`` to get the authenticated user; check
|
the metadata about the user (e.g., any appropriate roles or groups)
|
to verify access.
|
|
- If the access check fails because the user is not yet authenticated,
|
redirect to the ``login`` view, with a ``came_from`` value of the
|
current URL.
|
|
- If the access check fails for authenticated users, return a
|
403 Forbidden response.
|
|
In the login view:
|
|
- For ``GET`` requests, show the login form.
|
|
- For ``POST`` requests, validate the login and password from the form.
|
If successful, call ``api.remember``, and append the returned headers to
|
your response, which may also contain, e.g., a ``Location`` header for
|
a redirect to the ``came_from`` URL. In this case, there will be
|
no authenticator plugin which knows about the login / password at all.
|
|
In the logout view:
|
|
- Call ``api.forget`` and append the headers to your response, which may
|
also contain, e.g., a ``Location`` header for a redirect to the
|
``came_from`` URL after logging out.
|
|
|
More complex: multiple applications with "single sign-on"
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
In this scenario, authentication is "federated" across multiple applications,
|
which delegate to a central "login application." This application verifies
|
credentials from the user, and then uses headers or other tokens to
|
communicate the verified identity to the delegating application.
|
|
In the login application:
|
|
- The SSO login application works just like the login view described above:
|
the difference is that the configured identifier plugins must emit
|
headers from ``remember`` which can be recognized by their counterparts
|
in the other apps.
|
|
In the non-login applications:
|
|
- Challenge plugins here must be configured to implement the specific
|
SSO protocol, e.g. redirect to the login app with information in the
|
query string (other protocols might differ).
|
|
- Identifer plugins must be able to "crack" / consume whatever tokens are
|
returned by the SSO login app.
|
|
- Authenticators will normally be no-ops (e.g., the ``auth_tkt`` plugin
|
used as an authenticator).
|
|
Hybrid Use Cases
|
----------------
|
|
Examples of using the :mod:`repoze.who` API in conjuntion with its middleware.
|
|
Most complex: integrate Trac and the wiki behind SSO
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
This example extends the previous one, but adds into the mix the
|
requirement that one or more of the non-login applications (e.g., Trac)
|
be used "off the shelf," without modifying them. Such applications can
|
be plugged into the same SSO regime, with the addition of the
|
:mod:``repoze.who`` middleware as an adapter to bridge the gap (e.g.,
|
to turn the SSO tokens into the ``REMOTE_USER`` required by Trac).
|
|
In this scenario, the middleware would be configured identically to the
|
API used in applications which do not need the middleware shim.
|