repoze.who Use Cases

How should an application interact with repoze.who? There are three main scenarios:

Middleware-Only Use Cases

Examples of using the 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 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 repoze.who API without its middleware.

Simple: Wiki with its own login and logout views.

This application uses the 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 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.