httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Cliff Woolley" <jwool...@wlu.edu>
Subject Re: Multimodal authentication
Date Mon, 03 Jan 2000 01:44:30 GMT
>>> Doug Luce <doug@newhttpd.con.com> 01/02/00 02:19PM >>>
>If all modules return DECLINE instead of an error, don't you end up
with
>an error being transmitted to the browser, and a line like
"configuration
>error: couldn't check user.  No user file?" in your error log? 
Wouldn't
>it be better to have a message like "Nobody wants to authenticate
you"
>be sent?

That's correct.  You get a 500 Server Error.  That's why you have to
make sure that the last one (and only the last one) in line *IS*
authoritative.  =-)  That way, the client either gets 200 OK, 401 Auth
Required, or 403 Forbidden, but never 500 Server Error (all else being
equal).

>This also doesn't map onto the semantics of "If I didn't authenticate
this
>user, I shouldn't check their access."  mod_auth, even in
>non-authoritative mode, will try to validate access anyway.  Of
course, if
>it fails, it DECLINES and lets the next module have a try.  But if
another
>module authenticates a user, and applies different access logic to
their
>group membership, mod_auth might be stomping on some toes (or vice
versa,
>causing problems controlling precedence through module order in
>Configuration.tmpl).  While I don't think this would be a problem in
my
>specific case, I don't think this is good in general.

This is done intentionally, though, because authenticating the user and
allowing access are different processes, and you might WANT to have a
different module allow access than the one that validated that user was
who he said he was.  It just happens to be frequently convenient to do
these two things in the same module, but it doesn't have to be that way.
 You could even split out the logic for the standard "require"
statements from mod_auth into a separate module if you wanted, and it'd
all still work (see below).  If you think about it, most of the logic
for (simple) require statements is duplicated across modules anyway.  It
makes sense that the first module that can grok the require statement
and knows to let the user in should, regardless of whether or not that's
the same module that validated the user's identity... it's more
efficient to let simple cases be handled by the first module in line
that can handle them.  You just have to be careful in your
configuration, that's all.  Granted, it's less efficient than ONLY
running the check_access hook for the module that validated the user,
but then that causes the problem of FORCING the duplication of code for
the simple cases across modules when it's not needed (even though it'd
probably be done anyway, it doesn't *have to* be that way).

>There's two problems here: a module trying to check access on a user
it
>didn't authenticate, and the standard require statements being
interpreted
>by different modules.

These are either problems or benefits, depending on how you look at it.
 =-)  I tend to think of them as benefits.  Here's why.  Assuming you
have it set up right so that only the last auth module is authoritative,
then most of the modules will never *fail* a person on an access
check... they will only return DECLINED or OK.  Only the last
(authoritative) module will fail the person.  It doesn't matter which
module returns OK along the line, as long as that module is correct in
doing so.  Therefore no module will ever "step on toes" if they're all
configured right.

The standard require statements vs. non-standard ones are a good
example of this: it works either way.  (I tend to like the standard one
because it's standard. <grin>)  Take the case of standard requires
first.  Let's say you "require user bob".  It doesn't matter which
module validated that this request came from "bob".  The first module
that understands this statement (mod_auth in the example I gave earlier)
has the authority to say that "bob" is allowed access to this resource. 
For a more complicated require like "require context /.mktg.acme" from
mod_auth_nds (again using my earlier example), mod_auth would decline
because it doesn't understand "require context".  mod_auth_nds would
then either allow or disallow access because it does understand that
syntax.  No problems there.  Even for a "require valid-user", you're
still okay.  This case even comes pretty close to being what you seem to
want.  Using the earlier example, assume that the person who
authenticated was an NDS user.  mod_auth doesn't recognize that the
person is a valid-user because the person isn't in the .htpasswd file. 
mod_auth_nds *does* recognize that it's a valid-user because the person
*is* in the .ndsusers file.  It happens that mod_auth_nds was also the
module that authenticated the user in the first place.  That doesn't
really matter, but it worked out that way anyway.

Now take non-standard require variants (like "LDAPrequire" or
whatever).  This basically works out to be the same argument as what I
said for "require valid-user" a second ago.  It works.  Take my earlier
example and use mod_auth_ldap instead of mod_auth_nds.  Now it works
exactly the same whether or not mod_auth_ldap happens to use
"LDAPrequire group" or "require group", except that in the earlier case,
mod_auth_ldap has to duplicate a little more logic in processing the
require line.  Let's say you have an LDAP user who's authenticating and
who is in your allowed LDAPrequire'd group.  If it uses "LDAPrequire
group", then mod_auth would just decline because there were no "require"
lines it understood.  mod_auth_ldap would pick it up, verify that the
person was in the LDAPrequire'd group, and allow access.  If
mod_auth_ldap used the standard "require group" instead, it'd be exactly
the same: mod_auth would understand the require line, but it woudn't be
able to verify that the person was in the require'd group because that
person wasn't in the AuthGroupFile (if there was even one specified...
that doesn't matter).  mod_auth_ldap would then pick up the "require
group" line, verify that the person *was* in a group that it knew about,
and allow access.

You could even mix-and-match if you wanted, and that would work just as
well:

require user  some-htpasswd-user some-ldap-user some-other-ldap-user

Bottom line: all of this works either way, so isn't it easier on the
end user to have standard config directives?

Now one interesting point that this all brings up is that I don't think
that mod_auth handles the AuthAuthoritative directive precisely
correctly for subdirectories of protected directories that don't have
.htaccess files of their own.  But the solution there is a rather easy
fix to mod_auth, not a change in the core logic at all.  I'll start
another thread to gather opinions on that one.

--Cliff

Cliff Woolley
Central Systems Software Administrator
Washington and Lee University
http://www.wlu.edu/~jwoolley/

Work: (540) 463-8089
Pager: (540) 462-2303

Mime
View raw message