[Web-SIG] Communicating authenticated user information

Clark C. Evans cce at clarkevans.com
Wed Jan 25 07:53:38 CET 2006

On Wed, Jan 25, 2006 at 12:41:01AM -0500, Michal Wallace wrote:
| Unfortunately, if you require it to be the exact same 
| *object* then you're making the requirement that 
| everything in the stack happens in the same process, 
| on the same machine. 

Correct.  Phillip's extension APIs approach has the same short-coming;
it does seem that using response headers is the only sane way to go
about solving this problem.

| That means you can't distribute the magic over xml-rpc or SOAP
| or some other protocol, and you might want to do that if you're
| using a load balancing feature or want part of the system
| to run as a different user.

In other words, each WSGI component in a stack should, ideally, not be
dependent upon mutable objects and should only use values that can be
passed by value. It's additional work; but I'll buy that one -- I just
don't buy the idea that extension APIs are superior to just requring the
``environ`` be constant through a given request.

This seems to be where Phillip is headed:

    On Tue, Jan 24, 2006 at 11:37:30PM -0500, Phillip J. Eby wrote:
    | WSGI is designed for functional composability.  Requiring
    | environ passthrough breaks that by creating a global coupling.
    | If anything, in a 2.x WSGI version I would lean towards getting
    | rid of extension APIs and replacing them with some kind of
    | additional response facility, as it's still too easy to create
    | global coupling or to bypass middleware via extension APIs.

On Tue, Jan 24, 2006 at 11:37:30PM -0500, Phillip J. Eby wrote:
| I don't see why an extension API placed in the environ, such as 
| "paste.auth.set_user" doesn't satisfy this use case.

I must not have explained the modules clear enough; sorry for the
repetition, but let me take another stab at it.  

I have several authentication modules, one for HTML form authentication,
basic, digest, and quite a few others.  The function of these modules is
to ensure that environ['REMOTE_USER'] exists.  If a remote user is
already provided, they are a no-op.  Otherwise, they do what is
necessary (a 401, 302, returning an HTML form, etc.) in order to
get a remote user and fill in the environ.

Then I have a class of restoration modules, one which uses a signed key,
and another one that does path re-writing.  These modules look to see if
they have enough information to fill in a REMOTE_USER, if not, they are
a no-op on the way in.  On the way out, however, they *look* at the 
``environ`` to see if REMOTE_USER was set -- if it was set they do 
what ever they need to *save* this information.

Hence, the interfaces between these modules is simply using the
well-understood CGI variable ``REMOTE_USER``.  They can be used
independently of each other, and in creative combinations.

| You lost me.  How does it do that in any way that the 'REMOTE_USER' 
| variable does not?

Let's talk about both sorts of modules independently.  First, the CGI
variable 'REMOTE_USER' is already well documented; and the goal of the
authentication modules is simple -- fill in that environment variable.
Your approach requires that an additional activity/burden is imposed on
these sorts of modules.

I agree that the cookie module isn't quite as straight-forward, but
it isn't that bad.  Since the authentication modules are already
filling in the 'REMOTE_USER' to meet the expectations of standard
software components, it makes sense to obtain that inforamtion
directly from the environment.

In summary, I think extension APIs are more brittle and are a 
poor substitute for just using a shared environ both up and
down the WSGI stack.

| >So, I reject this approach, and I suggested that the same ``environ``
| >object should be passed all the way down the WSGI stack.
| And as I've already said, this simply isn't possible in WSGI 1.x, as 
| it's not backward compatible.  That needs to be a 2.x revision, if it 
| happens at all.

The WSGI middleware components that actually create their own environ
are few and far between.  This is an uncommon edge case.

| >Ian presented 2 use cases in paste where a different environ
| >is passed down the stack, however, both of his cases can be fixed (as I
| >demonstrated) to be compliant with the suggested wording above.
| So we can make it harder for people to write middleware, in order to 
| make it easier for people to introduce global coupling?  That doesn't 
| sound like a useful tradeoff -- certainly not one that overcomes the 
| cost of changing the spec.

The change needed is trivial and minor compared to most other things you
have to get correct while writing WSGI middleware; and given the
relative immaturity of WSGI at this point (especially in edge cases like
this), I doubt it is the problem that you make it out to be.

In summary; I think that a response-headers approach as proposed by
Phillip is the best (but higher overhead) approach.  However, I disagree
that some sort of extension API is preferable to just keeping the
``environ`` constant throughout the request.



More information about the Web-SIG mailing list