Zope3 PAU, redeux
I finally feel like I have a pretty good handle on Zope3's PAU. The pieces that had been confusing me have kinda fallen into place.
Admittedly, for things to "make sense" for me, I ended up writing my own PAU (not from scratch, but overriding the significant methods for PluggableAuthentication out of zope.app.authentication.authentication). I also overrode PrincipalFolder to authenticateCredentials in the way I wanted to, as well as created a credentials plugin to check both session and potential cookie data.
I had to build my own PAU because I needed my authenticated principals and principal info objects to return ConsumerPrincipal's and ConsumerPrincipalInfo objects, rather than PrincipalInfo and Principal's. pau, when pau.authenticate is called, actually re-runs AuthenticatedPrincipalFactory and adapts a Principal object out of the stored PrincipalInfo from the PrincipalFolder. because i built my own ConsumerPrincipals to store in my own ConsumerPrincipalFolder, i couldn't just drop them into the standard pau and get back principals that actually had all of the info i wanted from them. because my consumer principals were able to be adapted back down to the simpler level (Principal and PrincipalInfo) from which they were originally derived, this was, for some time, a transparent action. but when i needed to get principal.organization, which was one of my ConsumerPrincipalInfo extra fields, it wasn't available. on tracking it down, I realized what had happened.
I suppose that's the trouble with adapters, is that if you don't know they're performing an adaption operation behind the scenes, you may not always end up with the kind of object you think you should be getting, based on where it's adapting from.
I don't know enough about dynamic module loading/unloading from a particular memory space to really suggest it, nor do I fully understand the potential security issues (though I think if the dynamically loaded module is protected in the correct ways in zcml, it shouldn't be much of an issue), to really suggest a "how" for this...
but for the PAU, to make it more generic, and really "pluggable", since the way it stands now, it's only "pluggable" so long as you use a standard principal and principalfolder, i would be interested in seeing if the pau could inspect the kind of principalinfo obj being adapted, and return a principal obj of the intended type. might require a kind of registry between principalinfo, principal, and principalfolder though. right now though, if you add features to your own implementation, they don't translate through.
probably just smarter/simpler to leave the onus of the adapter building to the developer who needs other functionality. still, it would have been nice to know at the outset that pau.authenticate just wasn't going to give me the kind of principal i had actually created.
Oh well. Point is, I understand how it works now, and have created my own authentication implementation that overrides and provides all the necessary bits. works out just as well, since i was going (am going) to need to change the way "checkPassword" works anyway, since right now it forces a run of "encodePassword" for sha password managers. theoretically that's what you'd want, but i'd rather sha-hash the password the moment it's posted to the form, and then store the hash in the session, as well as in the cookie. i just feel slightly more secure that way.
Admittedly, for things to "make sense" for me, I ended up writing my own PAU (not from scratch, but overriding the significant methods for PluggableAuthentication out of zope.app.authentication.authentication). I also overrode PrincipalFolder to authenticateCredentials in the way I wanted to, as well as created a credentials plugin to check both session and potential cookie data.
I had to build my own PAU because I needed my authenticated principals and principal info objects to return ConsumerPrincipal's and ConsumerPrincipalInfo objects, rather than PrincipalInfo and Principal's. pau, when pau.authenticate is called, actually re-runs AuthenticatedPrincipalFactory and adapts a Principal object out of the stored PrincipalInfo from the PrincipalFolder. because i built my own ConsumerPrincipals to store in my own ConsumerPrincipalFolder, i couldn't just drop them into the standard pau and get back principals that actually had all of the info i wanted from them. because my consumer principals were able to be adapted back down to the simpler level (Principal and PrincipalInfo) from which they were originally derived, this was, for some time, a transparent action. but when i needed to get principal.organization, which was one of my ConsumerPrincipalInfo extra fields, it wasn't available. on tracking it down, I realized what had happened.
I suppose that's the trouble with adapters, is that if you don't know they're performing an adaption operation behind the scenes, you may not always end up with the kind of object you think you should be getting, based on where it's adapting from.
I don't know enough about dynamic module loading/unloading from a particular memory space to really suggest it, nor do I fully understand the potential security issues (though I think if the dynamically loaded module is protected in the correct ways in zcml, it shouldn't be much of an issue), to really suggest a "how" for this...
but for the PAU, to make it more generic, and really "pluggable", since the way it stands now, it's only "pluggable" so long as you use a standard principal and principalfolder, i would be interested in seeing if the pau could inspect the kind of principalinfo obj being adapted, and return a principal obj of the intended type. might require a kind of registry between principalinfo, principal, and principalfolder though. right now though, if you add features to your own implementation, they don't translate through.
probably just smarter/simpler to leave the onus of the adapter building to the developer who needs other functionality. still, it would have been nice to know at the outset that pau.authenticate just wasn't going to give me the kind of principal i had actually created.
Oh well. Point is, I understand how it works now, and have created my own authentication implementation that overrides and provides all the necessary bits. works out just as well, since i was going (am going) to need to change the way "checkPassword" works anyway, since right now it forces a run of "encodePassword" for sha password managers. theoretically that's what you'd want, but i'd rather sha-hash the password the moment it's posted to the form, and then store the hash in the session, as well as in the cookie. i just feel slightly more secure that way.
0 Comments:
Post a Comment
<< Home