On 1/13/06, Gary Poster <[EMAIL PROTECTED]> wrote: > > Comparing the id attribute works. Is it reasonable to assume that > > zapi.principals().getPrincipal(request.principal.id) should return the > > same principal as request.principal? And thus if > > somerecord['creator_id'] == request.principal.id, that's considered a > > good match? > > Yes. We compare on principal id. > > I believe it would be relatively easy to set up your system in such a > way that this would not be safe. For instance, you could have two > sites, both with authentication utilities. If each authentication > utility had the same prefix and had a user with the same key in the > auth utility, then you would have two different users with identical > ids in the system.
I was thinking of that, and the possibility that (somehow) the system could be hijacked in a way that after authentication a different utility would respond first to getUtility(IAuthentication) and provide a different matching principal for the principal id. I don't know how big of a concern that is. It might fall into the realm of "if your code is doing that, it's stupid; if some other code managed to do that, you're probably severely hacked anyways and this is the least of your problems." What I'm saying is that I'm not sure what a security auditor would look for in a situation like this. For our applications right now, we're not too concerned about really tight security, so if I know that comparing the IDs is good enough, I'd just go ahead and do that. I have a feeling that it might not be enough for everybody. I know that Zope 2 would keep track of the authentication path, and its entries in the transaction log include the path to the acl_users the user came out of. I think most other people using RDBMS systems for managing users or storing a user id in the RDBMS didn't use this, and would basically store just the user id. I guess most people found that good enough..? > It might be reasonable to add a bit to the IPrincipal interface that > __eq__ is provided and uses id to compare. That seems reasonable to > me, but maybe others have qualms. Care to write a mini-proposal? ;-) I'm interested in what others think. Other people here have a deeper knowledge of the security policies, principals, than I do. I don't know if this is something that should be pluggable - IComparablePrincipal? - so that a tighter security policy (I guess?) could compare principals on more than the ID. Since IPrincipals aren't locatable, you can't really compare the path that yielded the principal. That's the part that I'm unsure about - if it's possible (or worth worrying about) for a getPrincipal() call later in a request to yield a different result than it would have when request.principal was set. So maybe something that wanted tighter control and wanted to compare not just the id but the authentication utility that yielded the Found or Authenticated principal could listen for the respective events (zope.app.authentication.interface.FoundPrincipalCreated | AuthenticatedPrincipalCreated) and tag the principal with information about the authentication utility that provided it, such as the path (if the authentication utility is locatable). The adapter then says the principal directly provides IPathAwarePrincipal. An IComparablePrincipal adapter is provided for IPathAwarePrincipal that compares the paths of two principals as well as the id. It seems like a heavy scenario, and again I add the disclaimer that for me it doesn't matter much for our current customers and people who think harder about security may have better insight, but it seems like a way to allow applications to install stricter comparisons so that any code - regardless of where it is or who wrote it - can do something like: # obj.author = 'foo.user.1' owner = zapi.principals().getPrincipal(obj.author) if owner == request.principal: # it's the owner. that code stays simple, natural, and "pythonic" (no need to remember looking up something like IPrincipalComparator as a utility or adapter), but comparison can be rich if the application wants. I've already found one spot in Python code that does a comparison like this, and it works for global registry principals. Regardless of how it's made to work, it should work for all. At the same time, I recognize the desire to keep the zope.security.interfaces.IPrincipal interface small, so I'm not sure what to suggest. Since comparison works fine for global registry items, maybe __eq__ should just be put into zope.app.authentication.principalfolder.Principal since that's what's created by the default Found / Authenticated principal factories? Or is the answer "if this is something you care about, provide your own principal factories for pluggable auth that provide the principal you want and don't pressure the core to do more?" _______________________________________________ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com