[Zope-dev] Domain Login Slowness at certain location

Chris McDonough chrism@zope.com
18 Jun 2003 17:03:14 -0400


On Wed, 2003-06-18 at 16:07, Andrew R. Halko wrote:
> 
> Hello All,
> 
> I set up an Intranet that is based on visitors IP Address.  I made a
> tutorial at Plone.org
> (http://plone.org/documentation/howto/HowToDomainIntranet).  Now my
> problem is that I am experiencing a lot of slowness for someone that is
> within the domain, but it is only within this one location.  So, if I
> set the site to check my address and log me in, there is not slowness.
> But if I change the site to log people in automatically if they have the
> ip address for the gateway at the location, it is very very slow loading
> for all of them.
> 
> Does anyone know the processes that the domain attribute goes through to
> log people in?  Or maybe have an idea what could cause it?  I am trying
> to diagnose and I am not sure what could cause it.  It is the mixture of
> the automatic login and firewall or something else at the location.  Any
> ideas?  Thanks

The code to support this "domain auth" feature is perhaps the stupidest
part of Zope.access control.  I am disappointed that it is still
supported.  Here is the code to support this mode of authentication,
ripped directly from the AccessControl.User module:

        # we need to continue to support this silly mode
        # where if there is no auth info, but if a user in our
        # database has no password and he has domain restrictions,
        # return him as the authorized user.
        if not auth:
            if self._domain_auth_mode:
                for user in self.getUsers():
                    if user.getDomains():
                        if self.authenticate(user.getUserName(), '',
request):
                            if self.authorize(user, a, c, n, v, roles):
                                return user.__of__(self)


So this means, in essence, on each request, *for each user in the
system*, check if he he has domain restrictions, if so is able to get in
to the site with a blank password.  For a site with many users,
iterating over each user, checking for his domain restrictions, and so
on can take a long time.  And note that this doesn't just happen on one
request, it happens on *every* request.  Worse, it doesn't just happen
for requests that happen to come from the domain upon which you've
placed domain restrictions, it happens for *all* requests except the
ones that pass in auth credentials via HTTP (from people who have
already presented a valid username/password).  This is almost certainly
the cause of the slowness you see.

I have been trying to remove this feature for quite some time.  I can
see its utility but the implementation is just way too stupid to be used
for anything but tiny user databases.

One possible hack that might make things much faster *for the people in
the domain you're trying to allow access from* is to make sure that the
*first* user returned by getUsers is the user that has the domain
restrictions and blank password.  A simple way to do this is to name
that user "AAAA User" (because the default user folder's getUsers sorts
the users by the lexical order of their names).  This way the loop above
will at most be gone through once for browsers in the domains you
mention in that user's domain spec.

This will not be the case for anonymous users.  They will go through the
whole user database for every request and only fall off the end of the
userlist once they've tested every user.  It will thus be just as slow
for them.

HTH,

- C