On Sun, Jan 13, 2013, at 6:39, Glyph wrote:
> 
> On Jan 10, 2013, at 6:41 AM, Peter Westlake <peter.westl...@pobox.com>
> wrote:
> 
> > On Wed, Jan 9, 2013, at 18:02, Glyph wrote
> >> On Jan 9, 2013, at 9:26 AM, Peter Westlake <peter.westl...@pobox.com>
> >> wrote:
> >>> On Jan 9, Adi wrote:
> >>>> I am not an expert in Twisted, but from my understanding, the "string"
> >>>> requirement is there to provide a plugable interface. So that you can
> >>>> have generic credentials checkers, working with generic realms.
> >>>> Having simple "strings" could also help with AvatarId serialization,
> >>>> in case you have the CredentialsChecker on one computer and the you
> >>>> will pass them over network/socket to a remote Realm.
> >>> 
> >>> Those are both good points! I'll leave it this way until there's
> >>> a more official way of doing it.
> >> 
> >> I hope it's clear that just hard-coding your avatars and realms to work
> >> only with each other is a sub-optimal solution :).
> > 
> > Indeed :-)
> > 
> >> The architecture of cred is supposed to be that you can plug realms and
> >> checkers together so that a change to your authentication backend doesn't
> >> completely change your application.  Of course, that architecture is
> >> flawed in the sense that a string is a bit too narrow of a communication
> >> channel to get information about the authenticated user from one to the
> >> other, especially in cases where the application needs information from a
> >> directory service to function.
> >> 
> >> If you're interested in an improved, official way to deal with this
> >> use-case, the best way to do that would be to get involved and actively
> >> try to specify what you need.
> > 
> > Here's my use case. The CredentialsChecker takes a login name,
> > e.g. "pwest", and looks it up in LDAP. It gets back an LDAP record
> > something like this:
> > 
> > {
> >   'distinguishedName': 'CN=Peter Westlake,OU=User
> >   Accounts,OU=EMEA,DC=example,DC=com',
> >   'cn': 'Peter Westlake',
> >   'name': 'Peter Westlake',
> >   'sn': 'Westlake',
> >   'mail': 'peter.westl...@example.com',
> >   'givenName': 'Peter',
> >   'sAMAccountName': 'pwest'
> > }
> > 
> > It passes the distinguishedName and the supplied password
> > to the LDAP password checker function for authorization.
> > 
> > At this point the correct thing to do would be to return "pwest"
> > as the avatarId. But I've got all that other useful information
> > available, and it seems a shame to have to get it again in
> > the Realm, so I return the whole dictionary.
> 
> One potentially interesting question here, as well, is "why
> sAMAccountName" as the avatarID?  Isn't there a UID or UUID in there
> somewhere?  In my application, all the user identifiers are opaque, and
> that makes a bit more sense, since those values don't change, although
> any other part of the user's record could change as information evolves
> over time.  For example, if someone gets married and changes their name,
> they might find it annoying to have to log in with a username that
> references their maiden name all the time.

That would be a good design, yes, and I'll bear it in mind for future
use.
But for now I'm stuck with a system that has no way to change usernames,
as I discovered the hard way when my original employer was acquired. To
this day I have different logins for Unix and the rest of the corporate
infrastructure. (In case someone asks: the Unix name would be easy
enough to change, but it's used in a lot of places. One day, maybe.)
The account name is the closest thing to a unique id that's available.

> > Some points to note:
> > 
> > 1. Converting the dict to a string would make
> >   the avatarId conform to the interface, but
> >   it still wouldn't be pluggable, because other
> >   checkers wouldn't return the extra information.
> > 
> >   This strikes me as a general problem. If the
> >   checker returns more than an avatarId, whether
> >   directly or through some official-sanctioned channel,
> >   it will only be interchangeable with other
> >   checkers that also return the extra information.
> > 
> > 2. The application knows about LDAP, and uses it
> >   to find things like your manager and your email
> >   address. Some of this information is in the
> >   avatarId, but some of it isn't, so some LDAP
> >   calls will have to be made. This weakens the
> >   argument against duplicating the lookup.
> > 
> > The correct thing to do in this case would undoubtedly
> > be to accept that an LDAP call isn't very expensive,
> > and repeat it in the Realm. In other words, my use
> > case isn't very compelling. You have shamed me into
> > changing it :-)   In one way this is a good result,
> > though it doesn't help with the design.
> > 
> > Having made that change, I can use a password file
> > or an in-memory database for testing, and write
> > test scripts that don't need a real password. That's
> > well worth the /completely unnoticeable/ expense
> > of an extra LDAP call!
> 
> As other posters have already said, you can also have your realm and your
> checker share a reference to an object that caches credentials.  This
> would also let you cache other calls that are made later, too.
> 
> > BUT:
> > This only works because it doesn't use the user's
> > password for binding to LDAP. If it did, then either
> > the password or the LDAP session would have
> > to be made available to the Realm, and we're
> > back at square 1.
> 
> It seems like the "shared caching reference" would solve this problem
> as well?

Yes, I think that's the right answer. It's certainly the right design
in my case, and perhaps in the general case too.

Thanks for looking into this,

Peter.

_______________________________________________
Twisted-Python mailing list
Twisted-Python@twistedmatrix.com
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python

Reply via email to