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