-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Allow server admins to retrieve an auth token for any other user #366
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
First proposal is a new endpoint /_login_as/<username>, but could be any
other endpoint, even included in /_session, this is just to demonstrate
the feature.
On success, the endpoint returns a JSON object that looks like this:
{"auth_token": "amFuOjU2M0U0MDREOsGlD2HF6fday16PZGb0vIMDkWCw"}
It returns 404 for nonexistent user or when in admin party mode.
One use-case for this is building delegated authentication mechanisms
in middleware on top of CouchDB (like Oauth), while still being able
to log into CouchDB via it's native auth mechanisms without having
to proxy all requests and their variations, for e.g. replication.
This implementation is for 1.x.x for now (don't judge me), I'll
also supply a 2.x version.
|
Basically that's how Proxy Auth works and should be used for. |
|
|
|
@kxepal not quite, I do want to hand out auth tokens for existing CouchDB users, not populate a userCtx from an external source. |
|
@janl ok, than I have to ask what problem you're trying to solve. What is the use case. Because I don't see any difference between Proxy Auth. In both cases we have some middle ware. In both cases it have super privileges to run auth for any user. In both cases this used to run some requests in the name of some other user. And in both cases you know the user name you want for delegate the auth. The difference is in with what object you runs this delegated auth: with special headers or with a cookie. |
|
Whichever we use its time for sha-2 |
|
@kxepal the difference is you don't need to put couch behind a proxy |
|
@rnewson Can you elaborate this? Especially, how would you make this works without admin password leak? |
|
@janl What did I understand from this:
Is that correct? Questions:
I think some use case would be nice to see. |
|
@kxepal in the delegated_auth code, an admin calls _delegated_auth and gets a response body that includes a session cookie. the admin then gives that session cookie to someone else to use. In this case, typically, the 'admin' is a machine. |
|
I'm all +1 for making authentication and authorization more flexible The feature is complementary to proxy authentication in the following
I also have a use case for the feature. Together with @robertkowalski, I've been working on a small plugin that Previously, we would always set a new password for each sign-in, and Although we found a solution that matches our requirements, it took us |
|
I'd played around with both @janl and Cloudant solutions and figure out the cases when this feature becomes very useful. Sorry, I have to take back my scepticism (: However, important difference between these two implementations that Jan require to delegate auth for real and existed CouchDB user while Cloudant version acts more as Proxy Auth - you may delegate auth to any user, even non-existed ones. With given default 30 days timeout this makes things like token revoke very hard to make. I only found the one way is to change the salt what is basically means that I revoke all the tokens. With Jan's approach I can do this per user basis. In the same time it requires my app to register in CouchDB every user for which I will delegated auth with all the required roles. A little bit more work to do, but it brings more order in the house. Jan, please continue your work here. However, it's still not clear how users with delegated auth will handle expired token case (when we cannot prolong it automagically). CouchDB will return 401 please auth, but to auth I have to ask some third party service. Probably couch_httpd_auth with proper authentication_redirect will help here, but it's a feature that is hard to make it work properly /: Thoughts? |
|
@KlausTrainer Nice use case! Thanks for sharing (: |
|
@kxepal You're welcome :) Regarding token revocation with delegated authentication: You probably don't want to care about revoking tokens for individual users. The whole point of delegated authentication is to not care about such issues, I guess ;) You either trust the identity provider completely, or you don't trust it at all. That is, you do want to be able to revoke all tokens that have been issued by the identity provider, without revoking all other tokens (cookies) at the same time. Btw., regarding delegated authentication, I'd like CouchDB to support JSON Web Tokens (JWT). I created a working prototype for JWT support a while ago, see https://github.com/KlausTrainer/couchdb-couch/tree/jwt. The larger parts that are still missing are tests and documentation. I definitely want to get back to that, but feel like working on 2.0 blockers is a bit more important right now ;) |
|
@KlausTrainer Well, if I gave someone auth_token for my CouchDB and this someone started to do bad things there, I would like to make sure I can ban him. Yes, I can do that on my third party app side which runs delegated auth, but until he hold auth_token cookie and it's not expired he is still an active user for CouchDB. JWT support indeed would be nice. Not only as delegated auth, but as alternative to cookie one (because for some cases auth cookies are hard). But indeed, we need to finish blockers and broken compatibility issues first. However, if we can do both - that would be awesome (: |
|
Glad to see this is useful for people. @kxepal what should I be working on? My next step would be porting it to 2.x, or is there anything else you’d like to see addressed? |
I like the redirect bit. Would be a config option, like we do with Good point, too! |
Also, I thought about differences between your and Cloudant version...I think it's possible to have both behaviours:
I think both could be useful depending on the use case and that behaviour could be controlled by some config option. How do you feel with it? |
|
as for revocation as it pertains to this PR: it is no different than the cookie auth we use today. I believe the default timeout for that is 10 minutes: https://github.com/apache/couchdb/blob/master/rel/overlay/etc/default.ini#L85 |
Yea, and persistent cookies may bite you here. However, that's indeed not related to this PR, but about various possible cookie auth configuration. Users just need to be careful with. |
I’d prefer to do this one feature at a time, if possible. Definitely outside of this PR. |
|
Ok, fine. |
|
|
Anything else? :) |
|
Yes: you need to add test/etap/240-login-as.t to Makefile.am or it will be excluded for distcheck and these tests will never run. |
|
Oh, the redirect bit, yes, I’ll do that next.
Of course, thanks :D |
|
hm no, wait, where do I have to add this in |
|
oh in |
|
Yes, because this call will happens after tarball generation and autoconf won't include that test file there because it operates with the whitelist. |
|
Done |
|
Cool! Let's squash all together and I think it's done (: LGFM, thanks! |
|
I’ll have to ponder the redirect thing for a little longer. It would definitely work to keep this in the client, sure more work there, but they could have a logic of “if CouchDB API calls come back 401, talk to the auth server first for a new token”. Then we don’t have to know. |
|
Happy to land this as is, and decide upon the redirect helper later :) |
|
Indeed. Just an idea: pass URL for auth page with POST /_login_as and include it into cookie data. When it expires, extract that URL from cookie and redirect to there. |
|
nice one! :) |
|
+1 to all of this :) |
|
[off] @KlausTrainer , may be you also backport JWT auth to 1.7 for experiment? (; |
|
Linked 2.x versions above. @kxepal Can you help me port the 1.x tests to the new testing system? I experience very little experience with that. |
|
@janl Sure! Will handle it over today. |
|
@kxepal thank you! :) |
|
Ohai. Sorry, I eventually didn't expect such lack of free time week ago. Basically, what I did is turn your PR into pumpkin by dropping etap. Nothing personal, just improvements (: That only means, that we'll have the one test suite for this feature for both versions. Hold on and await PR for your fork to rebase. Thanks! |
|
@kxepal nothing to wait for as far as I am concerned. |
|
I'm going to close this out, simply because new feature development for 1.x has ended. I'd still very much like to see #373 and associated PRs get merged into 2.x, and/or Cloudant's delegated_auth repo instead. |
First proposal is a new endpoint /_login_as/, but could be any
other endpoint, even included in /_session, this is just to demonstrate
the feature.
On success, the endpoint returns a JSON object that looks like this:
{"auth_token": "amFuOjU2M0U0MDREOsGlD2HF6fday16PZGb0vIMDkWCw"}
It returns 404 for nonexistent user or when in admin party mode.
One use-case for this is building delegated authentication mechanisms
in middleware on top of CouchDB (like Oauth), while still being able
to log into CouchDB via it's native auth mechanisms without having
to proxy all requests and their variations, for e.g. replication.
This implementation is for 1.x.x for now (don't judge me), I'll
also supply a 2.x version.