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