[Twisted-Python] Something strange about cred
I think I've found the problem with trying to use my UserDbCredChecker with the web2 auth example. [The reason I'm posting this to the twisted list rather than twisted-web is because I think it points to a possible problem with cred (or at least some confusing names), which is not specifically web.] I believe the problem is with ICredentials. Its interface docstring says "I check credentials." -- first of all, this is counter-intuitive to me. IMO should either say "I *am* credentials", or else the interface should be "ICredentialsChecker" -- i.e., I think the checkPassword method it specifies should be provided by the ICredentialsChecker (if it is needed at all -- questionable). IMO ICredentials subinterfaces should only specify the types of credentials that are being provided (e.g., attributes username and password, for IUsernamePassword), and the checkPassword method should be in the ICredentialsChecker interface (and might not need to be public anyway -- all that needs to be public is requestAvatarId, really). Getting back to the web2 auth example, it appears that the checker's requestAvatarId method receives an ICredentials provider as its parameter, and my assumption was that the ICredentials provider would have attributes 'username' and 'password' -- which the IUsernamePassword interface docstring specifies as ivars (which I believe is incorrect syntax for a zope.interface definition -- I think they should be Attributes if they are supposed to be part of the interface specification) -- but I'm not sure it's getting them, because I think if it did my checker would work (i.e., would return an AvatarId (the username) from its requestAvatarId method). Comments? Steve
Here's a simple self-contained example of a database checker that's essentially identical to the one I use with my code which works with web but not with the web2 auth example (i.e., httpauth.tac). Perhaps someone familiar with cred and web2 could suggest how I might fix it? The only changes needed to make the web2 auth example use DbChecker instead of InMemoryUsernamePasswordDatabaseDontUse are (1) apply attached patch to httpauth.py, (2) drop dbchecker.py into the same directory. The test_dbchecker.py script is just a simple test to show that DbChecker returns an AvatarId when given a credential with correct username and password values. TIA for any help with this. Cheers, Steve P.S. Sorry I can't irc from work -- NASA/GSFC IT policy doesn't allow that. :(
On Thu, 08 Feb 2007 10:16:51 -0500, Stephen Waterbury <stephen.c.waterbury@nasa.gov> wrote:
Here's a simple self-contained example of a database checker that's essentially identical to the one I use with my code which works with web but not with the web2 auth example (i.e., httpauth.tac). Perhaps someone familiar with cred and web2 could suggest how I might fix it?
The only changes needed to make the web2 auth example use DbChecker instead of InMemoryUsernamePasswordDatabaseDontUse are (1) apply attached patch to httpauth.py, (2) drop dbchecker.py into the same directory. The test_dbchecker.py script is just a simple test to show that DbChecker returns an AvatarId when given a credential with correct username and password values.
TIA for any help with this.
Hey Steve, Aside from the cred questions/issues you raised in the first email (some of which I think are valid), I think the main problem you're running into is that HTTP digest authentication is being used, but the checker you wrote can't handle this: digest auth requires that the checker be able to handle IUsernameHashedPassword credentials, which yours doesn't. The reporting for this case could probably be improved. If there is no checker registered which can handle the kind of credentials being used, it's probably a programming error, and the programmer should be told about it. Jean-Paul
Jean-Paul Calderone wrote:
On Thu, 08 Feb 2007 10:16:51 -0500, Stephen Waterbury <stephen.c.waterbury@nasa.gov> wrote:
Here's a simple self-contained example of a database checker that's essentially identical to the one I use with my code which works with web but not with the web2 auth example (i.e., httpauth.tac). Perhaps someone familiar with cred and web2 could suggest how I might fix it?
The only changes needed to make the web2 auth example use DbChecker instead of InMemoryUsernamePasswordDatabaseDontUse are (1) apply attached patch to httpauth.py, (2) drop dbchecker.py into the same directory. The test_dbchecker.py script is just a simple test to show that DbChecker returns an AvatarId when given a credential with correct username and password values.
TIA for any help with this.
Hey Steve,
Aside from the cred questions/issues you raised in the first email (some of which I think are valid), I think the main problem you're running into is that HTTP digest authentication is being used, but the checker you wrote can't handle this: digest auth requires that the checker be able to handle IUsernameHashedPassword credentials, which yours doesn't.
The reporting for this case could probably be improved. If there is no checker registered which can handle the kind of credentials being used, it's probably a programming error, and the programmer should be told about it.
Jean-Paul
Thanks for the quick response, Jp! I was under the impression that this was just a basic auth example -- so if the basic auth thingy is getting a plain text (uuencoded, same thing) password from the app, why would it hash it before it gives it to the checker? Auggh! I can see the checker *storing* the password hashed (which my "production" checker does, using sha), but it seems to me pretty brain-dead to use hashed passwords over http when plaintext passwords over https are way, way more secure (and then all the checker has to deal with is plaintext passwds, which it can store hashed for extra security). Steve
Stephen Waterbury wrote:
Jean-Paul Calderone wrote:
On Thu, 08 Feb 2007 10:16:51 -0500, Stephen Waterbury <stephen.c.waterbury@nasa.gov> wrote:
Here's a simple self-contained example of a database checker that's essentially identical to the one I use with my code which works with web but not with the web2 auth example (i.e., httpauth.tac). Perhaps someone familiar with cred and web2 could suggest how I might fix it?
The only changes needed to make the web2 auth example use DbChecker instead of InMemoryUsernamePasswordDatabaseDontUse are (1) apply attached patch to httpauth.py, (2) drop dbchecker.py into the same directory. The test_dbchecker.py script is just a simple test to show that DbChecker returns an AvatarId when given a credential with correct username and password values.
TIA for any help with this.
Hey Steve,
Aside from the cred questions/issues you raised in the first email (some of which I think are valid), I think the main problem you're running into is that HTTP digest authentication is being used, but the checker you wrote can't handle this: digest auth requires that the checker be able to handle IUsernameHashedPassword credentials, which yours doesn't.
The reporting for this case could probably be improved. If there is no checker registered which can handle the kind of credentials being used, it's probably a programming error, and the programmer should be told about it.
Jean-Paul
Thanks for the quick response, Jp! I was under the impression that this was just a basic auth example -- so if the basic auth thingy is getting a plain text (uuencoded, same thing) password from the app, why would it hash it before it gives it to the checker? Auggh! I can see the checker *storing* the password hashed (which my "production" checker does, using sha), but it seems to me pretty brain-dead to use hashed passwords over http when plaintext passwords over https are way, way more secure (and then all the checker has to deal with is plaintext passwds, which it can store hashed for extra security).
Well, that was an incorrect and non-sequitur reply on my part, so apologies for that! I still think HTTP digest authentication is not very useful, but I do understand why web2 implements it, because it's part of the spec. No more griping, for now -- and I should say that everything *else* about web2 looks great so far! :) Steve
Jean-Paul Calderone wrote:
... I think the main problem you're running into is that HTTP digest authentication is being used ...
*So* (for anybody still listening ;) I finally figured out the implication of Jp's comment: all I had to do was remove the digest.DigestCredentialFactory('md5', 'My Realm') factory instance from HTTPAuthResource's list of credentialFactories and bingo, we're in basic auth mode and my checker works with the web2 auth example -- yay! That wasn't obvious to me from HTTPAuthResource's doc string nor from the example docs, but arguably I should have guessed it (sooner). Anyway, I'm happy now -- thanks, web2 team! Death to HTTP digest authentication! Cheers, Steve
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Feb 8, 2007, at 2:51 PM, Stephen Waterbury wrote:
Jean-Paul Calderone wrote:
... I think the main problem you're running into is that HTTP digest authentication is being used ...
*So* (for anybody still listening ;) I finally figured out the implication of Jp's comment: all I had to do was remove the digest.DigestCredentialFactory('md5', 'My Realm') factory instance from HTTPAuthResource's list of credentialFactories and bingo, we're in basic auth mode and my checker works with the web2 auth example -- yay!
Why doesn't your DB Checker just support both interfaces? IUsernamePassword, and IUsernameHashedPassword, doing the right thing depending on the interface provided by the credentials input. Or, do the same thing regardless, because they provide compatible checkPassword interfaces. You'd have to read the password from the DB here, but I don't see why that should concern you. And the ability to use Digest auth would provide all around better security.
That wasn't obvious to me from HTTPAuthResource's doc string nor from the example docs, but arguably I should have guessed it (sooner).
Anyway, I'm happy now -- thanks, web2 team!
You're welcome, sorry I didn't get a chance to chime in on this discussion earlier.
Death to HTTP digest authentication!
I don't know, I definitely prefer digest authentication[1] to sending my password in plaintext[2]
Cheers, Steve
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
David Reid http://dreid.org/ [1] I may be biased, i've spent a great deal of time on web2's digest implementation. In fact, all the work put into web2's HTTP auth support was so I could do digest, and one day Kerberos. [2] Yes I know base64 isn't plaintext, but it might as well be. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.5 (Darwin) iD8DBQFFy7ydrsrO6aeULcgRApErAJ9ER5Mi6HAdBP+7hku03n3DUiskigCfQgjq bp1IMXp0OixUOxkZoS0mn3g= =IYzd -----END PGP SIGNATURE-----
David Reid wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On Feb 8, 2007, at 2:51 PM, Stephen Waterbury wrote:
Jean-Paul Calderone wrote:
... I think the main problem you're running into is that HTTP digest authentication is being used ...
*So* (for anybody still listening ;) I finally figured out the implication of Jp's comment: all I had to do was remove the digest.DigestCredentialFactory('md5', 'My Realm') factory instance from HTTPAuthResource's list of credentialFactories and bingo, we're in basic auth mode and my checker works with the web2 auth example -- yay!
Why doesn't your DB Checker just support both interfaces? IUsernamePassword, and IUsernameHashedPassword, doing the right thing depending on the interface provided by the credentials input. Or, do the same thing regardless, because they provide compatible checkPassword interfaces. You'd have to read the password from the DB here, but I don't see why that should concern you. And the ability to use Digest auth would provide all around better security.
Thanks, David, but for my application it isn't useful. IMNSHO, digest auth only gives an illusion of good security -- it's encrypted, right? But I regard it as a waste of time, and the time that I have to work on the actual logic of my application is in short supply as it is. Digest auth was invented in 1993, well before widespread open source implementation of strong asymmetric key technologies, and digest auth is a technology that can be broken by determined hackers. I don't intend to bother with it -- especially since good transport layer encryption technology is now quite easy to use. I prefer to exclude digest auth completely from any of my applications, as I am campaigning against its use.
That wasn't obvious to me from HTTPAuthResource's doc string nor from the example docs, but arguably I should have guessed it (sooner).
Anyway, I'm happy now -- thanks, web2 team!
You're welcome, sorry I didn't get a chance to chime in on this discussion earlier.
Yes, it would have saved me half a day off-and-on of head-scratching.
Death to HTTP digest authentication!
I don't know, I definitely prefer digest authentication[1] to sending my password in plaintext[2]
I use either plaintext basic auth (if the need is only for user identification, not security) or transport layer asymmetric key encryption (if the resource needs security). If it needs security, it needs real security, and since twisted makes transport layer asymmetric key encryption (e.g., openssl) quite easy to use, the only reason I can see for bothering with digest auth is if you have either some legacy stuff that needs it (which I don't) or a pointy-haired boss who insists on it (time to look for another job! ... but one doesn't always have that opportunity, of course). There might be other use-cases, but I have surrounded them with a Somebody Else's Problem Field, so they are invisible to me. ;) Thanks for all your good work on web2 -- it is appreciated! :) Cheers, Steve
On Feb 8, 2007, at 7:01 PM, Stephen Waterbury wrote:
David Reid wrote:
Jean-Paul Calderone wrote:
... I think the main problem you're running into is that HTTP digest authentication is being used ...
*So* (for anybody still listening ;) I finally figured out the implication of Jp's comment: all I had to do was remove the digest.DigestCredentialFactory('md5', 'My Realm') factory instance from HTTPAuthResource's list of credentialFactories and bingo, we're in basic auth mode and my checker works with the web2 auth example -- yay! Why doesn't your DB Checker just support both interfaces? IUsernamePassword, and IUsernameHashedPassword, doing the right thing depending on the interface provided by the credentials input. Or, do the same thing regardless, because they
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Feb 8, 2007, at 2:51 PM, Stephen Waterbury wrote: provide compatible checkPassword interfaces. You'd have to read the password from the DB here, but I don't see why that should concern you. And the ability to use Digest auth would provide all around better security.
Thanks, David, but for my application it isn't useful. IMNSHO, digest auth only gives an illusion of good security -- it's encrypted, right? But I regard it as a waste of time, and the time that I have to work on the actual logic of my application is in short supply as it is.
Well relative merits of Digest authentication aside, it's trivial to make your DbChecker support the IUsernameHashedPassword of which there are providers other than web2's DigestedCredentials. So I feel like you're really missing out on some of the flexibility that is cred, but you seem to genuinely have no desire (and/or time) for anything more than basic auth so I won't harp on this point anymore. -- David Reid http://dreid.org/
David Reid wrote:
On Feb 8, 2007, at 7:01 PM, Stephen Waterbury wrote:
David Reid wrote:
Jean-Paul Calderone wrote:
... I think the main problem you're running into is that HTTP digest authentication is being used ...
*So* (for anybody still listening ;) I finally figured out the implication of Jp's comment: all I had to do was remove the digest.DigestCredentialFactory('md5', 'My Realm') factory instance from HTTPAuthResource's list of credentialFactories and bingo, we're in basic auth mode and my checker works with the web2 auth example -- yay! Why doesn't your DB Checker just support both interfaces? IUsernamePassword, and IUsernameHashedPassword, doing the right thing depending on the interface provided by the credentials input. Or, do the same thing regardless, because they
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Feb 8, 2007, at 2:51 PM, Stephen Waterbury wrote: provide compatible checkPassword interfaces. You'd have to read the password from the DB here, but I don't see why that should concern you. And the ability to use Digest auth would provide all around better security.
Thanks, David, but for my application it isn't useful. IMNSHO, digest auth only gives an illusion of good security -- it's encrypted, right? But I regard it as a waste of time, and the time that I have to work on the actual logic of my application is in short supply as it is.
Well relative merits of Digest authentication aside, it's trivial to make your DbChecker support the IUsernameHashedPassword of which there are providers other than web2's DigestedCredentials. So I feel like you're really missing out on some of the flexibility that is cred, but you seem to genuinely have no desire (and/or time) for anything more than basic auth so I won't harp on this point anymore.
Two things I should emphasize: (1) I do appreciate "the flexibility that is cred" -- even though I do not intend to use digest auth, I will most likely use other auth methods (e.g., LDAP) -- but only over an encrypted transport. Cred's flexibility and other well designed architectural features are the main reasons I use Twisted. (2) As I mentioned in my last message, I am campaigning against the use of digest auth here at NASA/GSFC, because when things here need protection, they need the best protection available, and that is *not* digest auth. The consequences for security compromises can be pretty dire -- e.g.: (a) NASA system compromises can be front-page news (along with other NASA-related misadventures, as we've seen over the past couple days ;) (b) government employees are personally liable for the release of ITAR data -- if it goes to the wrong people, the NASA employee responsible can get federal *prison* time. So you can see why the illusion of security that digest auth gives to naive people is not good enough for my apps or for any serious commercial or government applications. It might be useful for free on-line gaming communities, though. ;) Cheers, Steve
David Reid wrote:
Death to HTTP digest authentication!
I don't know, I definitely prefer digest authentication[1] to sending my password in plaintext[2]
+1 web2 auth is a much better architecture. I only spent a few hours looking at it (primarily looking at how Apples CalDAV server implemented SPNEGO - very neat) but it seemed to me that it could issue multiple WWW-Authenticate headers and the browser should pick and reply to the appropriate one. Was my understanding correct? If so, why did the digest checker cause this?
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Feb 9, 2007, at 3:24 AM, Phil Mayers wrote:
David Reid wrote:
Death to HTTP digest authentication! I don't know, I definitely prefer digest authentication[1] to sending my password in plaintext[2]
+1
web2 auth is a much better architecture.
I only spent a few hours looking at it (primarily looking at how Apples CalDAV server implemented SPNEGO - very neat)
The way Apple's CalDAV server uses web2 auth is kind of broken, please don't use it as an example of how to use cred. It does some very poor things because sometimes I'm an idiot.
but it seemed to me that it could issue multiple WWW-Authenticate headers and the browser should pick and reply to the appropriate one.
This is correct.
Was my understanding correct? If so, why did the digest checker cause this?
The problem wasn't with a Digest checker it was with the lack of a checker for the IUsernameHashedPassword credential interface. You still need to have a checker that implements the interface of whatever you are getting back from ICredentialFactory.decode. In basic this is IUsernamePassword, for digest this is IUsernameHashedPassword. - -- David Reid http://dreid.org/ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.5 (Darwin) iD8DBQFFzJ8frsrO6aeULcgRAmFUAJ4h2KV3NJzvC0E+tQwqLLjwrKxBdgCfZqNf Jcj7qrA1eYMrxPNQpaZp6/w= =uGwz -----END PGP SIGNATURE-----
participants (5)
-
David Reid -
Jean-Paul Calderone -
Phil Mayers -
Stephen Waterbury -
Stephen Waterbury