1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
.. _using_middleware:
Using :mod:`repoze.who` Middleware
==================================
.. _middleware_responsibilities:
Middleware Responsibilities
---------------------------
:mod:`repoze.who` as middleware has one major function on ingress: it
conditionally places identification and authentication information
(including a ``REMOTE_USER`` value) into the WSGI environment and
allows the request to continue to a downstream WSGI application.
:mod:`repoze.who` as middleware has one major function on egress: it
examines the headers set by the downstream application, the WSGI
environment, or headers supplied by other plugins and conditionally
challenges for credentials.
.. _request_lifecycle:
Lifecycle of a Request
----------------------
:mod:`repoze.who` performs duties both on middleware "ingress" and on
middleware "egress". The following graphic outlines where it sits in the context
of the request and its response:
.. image:: .static/request-lifecycle.png
.. _ingress_stages:
Request (Ingress) Stages
++++++++++++++++++++++++
.. image:: .static/ingress.png
:mod:`repoze.who` performs the following operations in the following
order during middleware ingress:
#. Environment Setup
The middleware adds a number of keys to the WSGI environment:
``repoze.who.plugins``
A reference to the configured plugin set.
``repoze.who.logger``
A reference to the logger configured into the middleware.
``repoze.who.application``
A refererence to the "right-hand" application. The plugins
consulted during request classification / identification /
authentication may replace this application with another
WSGI application, which will be used for the remainder of the
current request.
#. Request Classification
The middleware hands the WSGI environment to the configured ``classifier``
plugin, which is responsible for classifying the request into a single
"type". This plugin must return a single string value classifying the
request, e.g., "browser", "xml-rpc", "webdav", etc.
This classification may serve to filter out plugins consulted later in
the request. For instance, a plugin which issued a challenge as an
HTML form would be inappropriate for use in requests from an XML-RPC
or WebDAV client.
#. Identification
Each plugin configured as an identifier for a particular class of
request is called to extract identity data ("credentials") from the
WSGI environment.
For example, a basic auth identifier might use
the ``HTTP_AUTHORIZATION`` header to find login and password
information. Each configured identifier plugin is consulted in turn,
and any non-None identities returned are collected into a list to be
authenticated.
Identifiers are also responsible for providing header information used
to set and remove authentication information in the response during
egress (to "remember" or "forget" the currently-authenticated user).
#. Authentication
The middlware consults each plugin configured as an authenticators for
a particular class of request, to compare credentials extracted by the
identification plugins to a given policy, or set of valid credentials.
For example, an htpasswd authenticator might look in a file for a user
record matching any of the extracted credentials. If it finds one, and
if the password listed in the record matches the password in the
identity, the userid of the user would be returned (which would
be the same as the login name). Successfully-authenticated identities are
"weighted", with the highest weight identity governing the remainder of
the request.
#. Metadata Assignment
After identifying and authenticating a user, :mod:`repoze.who` consults
plugins configured as metadata providers, which may augment the
authenticated identity with arbitrary metadata.
For example, a metadata provider plugin might add the user's first,
middle and last names to the identity. A more specialized metadata
provider might augment the identity with a list of role or group names
assigned to the user.
.. _egress_stages:
Response (Egress) Stages
++++++++++++++++++++++++
:mod:`repoze.who` performs the following operations in the following
order during middleware egress:
#. Challenge Decision
The middleare examines the WSGI environment and the status and headers
returned by the downstream application to determine whether a
challenge is required. Typically, only the status is used: if it
starts with ``401``, a challenge is required, and the challenge
decider returns True.
This behavior can be replaced by configuring a different
``challenge_decider`` plugin for the middleware.
If a challenge is required, the challenge decider returns True; otherwise,
it returns False.
#. Credentials reset, AKA "forgetting"
If the challenge decider returns True, the middleware first delegates
to the identifier plugin which provided the currently-authenticated
identity to "forget" the identity, by adding response headers (e.g., to
expire a cookie).
#. Challenge
The plugin then consults each of the plugins configured as
challengers for the current request classification: the first plugin
which returns a non-None WSGI application will be used to perform a
challenge.
Challenger plugins may use application-returned headers, the WSGI
environment, and other items to determine what sort of operation
should be performed to actuate the challenge.
#. Remember
The identifier plugin that the "best" set of credentials came from
(if any) will be consulted to "remember" these credentials if the
challenge decider returns False.
|