iriscouch / browserid_couchdb

Mozilla BrowserID support plugin for CouchDB
Apache License 2.0
57 stars 9 forks source link

httpd authentication_handlers #6

Open gertcuykens opened 13 years ago

gertcuykens commented 13 years ago

Is it possible to make a handler in the config like this instead of browserid enabled true?

httpd authentication_handlers {couch_httpd_oauth, oauth_authentication_handler}, {couch_httpd_auth, cookie_authentication_handler}, {couch_httpd_auth, default_authentication_handler},{couch_httpd_browserid, browserid_authentication_handler}

jhs commented 13 years ago

I do not think so, because BrowserID is simply the process of creating normal users (documents in the _users database) and authenticating as those users. Once that happens, subsequent requests are authenticated through cookie authentication.

gertcuykens commented 13 years ago

but does that not count for {couch_httpd_oauth, oauth_authentication_handler} as well?

jhs commented 12 years ago

Yes. Great point.

I think the next problem is that the plugins is more than just an authentication handler, it also creates new accounts (autovivification) once they authenticate for the first time, since every possible email address is a valid account.

You have definitely persuaded me that an authentication module/config would be more standard. But what to do about requests to /_browserid to use its API? I definitely wanted this to be disabled by default. People probably do not want automatic account creation unless they explicitly ask for that. (There is also a denial of service vulnerability. An attacker could create a user document for unlimited addresses at some domain, such as mailinator.com, until the CouchDB server fills up its disk.)

Thoughts? Thanks!

gertcuykens commented 12 years ago

Maybe create two types?

one for authentication only {couch_httpd_browserid, browserid_authentication_handler}

one for new user registration {couch_httpd_browserid, browserid_registration_handler}

Only the browser id service provider (https://browserid.org/verify) should be able to request a create account right? So the security about the denial of service is there responsibility.

jhs commented 12 years ago

Well, another wrinkle is that the service provider is supposed to be a stopgap, CouchDB should really be confirming ids on its own but that requires more programming than I can allocate at this time (some crypto code at least, plus a deeper understanding of the BrowserID spec, plus possibly things like sending emails, I'm not sure.)

So, at this time, it's a trade-off, and by using this plugin (and most others at this time, I presume), you are trusting Mozilla to have a correct implementation, and to maintain the integrity and security of their web service.

Although I can't justify putting off work just because there is more work to be done later :)

jhs commented 12 years ago

Back to the pressing matter:

Does your idea of the two types change how CouchDB developers (I mean, people using CouchDB to build apps) would use it? One thing I am very proud and excited about with BrowserID is that it is actually the easiest user and authentication system to get going, partially by design, but also because of the reference implementation I included in /_browserid/.html, .js, etc.

So, is there a way to improve the inner architecture while still maintaining (or improving!) simplicity from the developer's perspective?

gertcuykens commented 12 years ago

The inner architecture should be transparent to the authentication method. If I would create a new _user directly into couchdb using curl -X PUT, the new created user should be able to login by all enabled authentication handlers in the config.

All existing users should be able to log in also without changing there _user document. "browserid": true in a _user document is not a good idea, there should be no difference between a normal _user and a browserid _user.

Any couchdb should be able to switch browserid on and off for all users by simple defining {couch_httpd_browserid, browserid_authentication_handler} in the config. Not by enabling it and then change a few million _user records with the authentication flavor of the day.

jhs commented 12 years ago

"browserid":true is not used by any code, I merely put it there to annoy you :)

But seriously, it doesn't do anything. I just thought it might be helpful for example if you and I share user accounts from people who use BrowserID. I can replicate from your _users database with a filter looking for "browserid":true. But as it stands, a user who signed up using BrowserID need only add password and salt values to their user document to start using password authentication on that couch. Similarly, if you sign up the old-fashioned way, and you had the foresight to make your username your email address, then you can log in immediately with BrowserID.

You are 100% correct that every user should be able to authenticate in any way. If the browserid plugin breaks that, that is definitely a bug. People routinely authenticate with either HTTP basic auth, or else a username/password form submission, but subsequent queries are authenticated via a cookie.

I am starting to see a solution to the problem you identify. Cookie authentication is triggered via form submission to the /_session URL. It seems like BrowserID belongs there. So, basically, if you submit username=me&password=secret, Couch will try password authentication, and if you submit assertion=<stuff> then it will try browserid authentication (if that is enabled).

Does that sound right to you? I think that is starting to sound like correct architecture. (The next question is whether it can be done as a third-party plugin. The reason I added a /_browserid path is because that is a very clean way to add functionality to CouchDB. It is not straightforward to "inherit" or "subclass" existing request handlers such as /_session although I have successfully done exactly that subsequent to writing this plugin, so it can be done. (Iris Couch dynamically serves stanard Futon or Mobile Futon for the /_utils path, using user agent inspection.)

gertcuykens commented 12 years ago

/_session would be ideal but /_browserid is acceptable like /_oauth or /_fb is. Its the fiddling with _users documents that should be 1) NOT recommended 2) a extra option like obscuring email addresses.

gertcuykens commented 12 years ago

Suppose https://browserid.org shuts down then the plugin could offer to send you a generated password to your email (_id) so you are able to login using the default handlers.