Authentication patches

I'm attaching a diff file with these patches for now. To recap:

Fixes two bugs:

  • eternal 'sending' screen on form upload
  • too many http requests on upload
    And adds one feature
  • preemptive authentication (reducing further the number of http
    requests on upload, so now there is only 1 POST on upload, the way it
    should be!)

Thanks!

toms-auth-patches.diff (5.46 KB)

Hi Thomas,

Does your server handle HEAD requests? If you can, you should add support
for those on the /submission url.

Upload should always be a HEAD request followed by a POST request. The HEAD
request allows the server to negotiate over to a secure channel (https)
before you send the POST. This ensures that form data is never sent
inadvertently in the clear due to a configuration error on the phone or in
the form's tag.

If your server supports HEAD requests, the authentication negotiation will
occur on the HEAD request. So you're not saving much by the preemptive
authentication (it doesn't hurt anything, but it isn't a big win with a HEAD
request).

Preemptive authentication is only useful for the basic authentication, which
it looks like you're using. Please note that with basic auth, you should
require HTTPS for all interactions between ODK Collect and your server, as
that is what ODK Collect assumes (e.g., even for /formList). You also
should have ODK Collect configured with https: URLs.

Out of the box, ODK Aggregate uses digest authentication, and that requires
a nonce from the server and therefore must be initiated by the server, so
preemptive authentication is impossible when communicating with vanilla ODK
Aggregate.

Mitch

··· On Thu, Jul 28, 2011 at 8:56 AM, Thomas Smyth wrote:

I'm attaching a diff file with these patches for now. To recap:

Fixes two bugs:

  • eternal 'sending' screen on form upload
  • too many http requests on upload
    And adds one feature
  • preemptive authentication (reducing further the number of http
    requests on upload, so now there is only 1 POST on upload, the way it
    should be!)

Thanks!

--
Mitch Sundt
Software Engineer

University of Washington
mitchellsundt@gmail.com

Does your server handle HEAD requests?

Yes.

If your server supports HEAD requests, the authentication negotiation will
occur on the HEAD request. So you're not saving much by the preemptive
authentication (it doesn't hurt anything, but it isn't a big win with a HEAD
request).

Actually in 1.1.7RC1, the authentication negotiation (Basic auth, this
is) is occurring on EVERY request. So every request is doubled. Unless
I'm mistaken, this is how non-preemptive basic authentication works.
With the code I've added in that patch, only the HEAD request happens
twice. So this is quite a big savings as the phone is not submitting
all the data twice.

Also due to another bug fixed in that patch, the app was actually
doing 3 POST requests. So the patch brings it from from 6 requests
total to 3, for Basic auth.

Please note that with basic auth, you should
require HTTPS for all interactions between ODK Collect and your server

Yes we're doing this. We need HTTPS anyway since all transmissions
need to be secure. That's why we decided to use basic auth as it was
easier to implement on the server side.

I am not sure if the code I have submitted would interfere with Digest
auth but I don't believe it would. Is that not what the AuthScope
mechanism is for?

Anyway you're free to use this patch or not. I am just happy that
things are working for my deployment. Thanks for your help.

Ah, OK.

My understanding of the typical server-side implementation of form-based
authentication is that after the authentication, the server would use a
cookie to maintain the identity of the user, and only when the cookie is
missing would you re-auth; I had thought basic authentication would work the
same way; if not, we'd clearly want the preemptive patch in for basic
authentication support.

ODK Collect is reusing the request context across calls so it will honor and
return cookies that the server establishes (can't do digest auth without
that).

Mitch

··· On Thu, Jul 28, 2011 at 10:58 AM, Thomas Smyth wrote:

Does your server handle HEAD requests?

Yes.

If your server supports HEAD requests, the authentication negotiation
will
occur on the HEAD request. So you're not saving much by the preemptive
authentication (it doesn't hurt anything, but it isn't a big win with a
HEAD
request).

Actually in 1.1.7RC1, the authentication negotiation (Basic auth, this
is) is occurring on EVERY request. So every request is doubled. Unless
I'm mistaken, this is how non-preemptive basic authentication works.
With the code I've added in that patch, only the HEAD request happens
twice. So this is quite a big savings as the phone is not submitting
all the data twice.

Also due to another bug fixed in that patch, the app was actually
doing 3 POST requests. So the patch brings it from from 6 requests
total to 3, for Basic auth.

Please note that with basic auth, you should
require HTTPS for all interactions between ODK Collect and your server

Yes we're doing this. We need HTTPS anyway since all transmissions
need to be secure. That's why we decided to use basic auth as it was
easier to implement on the server side.

I am not sure if the code I have submitted would interfere with Digest
auth but I don't believe it would. Is that not what the AuthScope
mechanism is for?

Anyway you're free to use this patch or not. I am just happy that
things are working for my deployment. Thanks for your help.

--
Mitch Sundt
Software Engineer
http://www.OpenDataKit.org
University of Washington
mitchellsundt@gmail.com

Yeah. My understanding of basic auth is that it does not use cookies.
It sends the base 64 encoded credentials with every request in the
headers. Without preemptive support, the httpclient is not even
consulting the httpcontext until it gets a 401, and this is so for
every request. That's why every request is doubled.

So perhaps you could test what I've done with a server running digest
auth (I don't have one). All I know is it's working beautifully on our
system, which is HTTPS, basic auth.

··· On 28 July 2011 14:16, Mitch Sundt wrote: > Ah, OK. > > My understanding of the typical server-side implementation of form-based > authentication is that after the authentication, the server would use a > cookie to maintain the identity of the user, and only when the cookie is > missing would you re-auth; I had thought basic authentication would work the > same way; if not, we'd clearly want the preemptive patch in for basic > authentication support. > > ODK Collect is reusing the request context across calls so it will honor and > return cookies that the server establishes (can't do digest auth without > that). > > Mitch > > On Thu, Jul 28, 2011 at 10:58 AM, Thomas Smyth wrote: >> >> > Does your server handle HEAD requests? >> >> Yes. >> >> > If your server supports HEAD requests, the authentication negotiation >> > will >> > occur on the HEAD request. So you're not saving much by the preemptive >> > authentication (it doesn't hurt anything, but it isn't a big win with a >> > HEAD >> > request). >> >> Actually in 1.1.7RC1, the authentication negotiation (Basic auth, this >> is) is occurring on EVERY request. So every request is doubled. Unless >> I'm mistaken, this is how non-preemptive basic authentication works. >> With the code I've added in that patch, only the HEAD request happens >> twice. So this is quite a big savings as the phone is not submitting >> all the data twice. >> >> Also due to another bug fixed in that patch, the app was actually >> doing *3* POST requests. So the patch brings it from from 6 requests >> total to 3, for Basic auth. >> >> > Please note that with basic auth, you should >> > require HTTPS for all interactions between ODK Collect and your server >> >> Yes we're doing this. We need HTTPS anyway since all transmissions >> need to be secure. That's why we decided to use basic auth as it was >> easier to implement on the server side. >> >> I am not sure if the code I have submitted would interfere with Digest >> auth but I don't believe it would. Is that not what the AuthScope >> mechanism is for? >> >> Anyway you're free to use this patch or not. I am just happy that >> things are working for my deployment. Thanks for your help. > > > > -- > Mitch Sundt > Software Engineer > http://www.OpenDataKit.org > University of Washington > mitchellsundt@gmail.com >

The patch should probably be changed to do preemptive auth only if the
target host port is 8443 or 443; what we really want to do is only send
credentials if the intended scheme is https, but I don't know how to do
that.

Anyway, that's Carl's business...

Mitch

··· On Thu, Jul 28, 2011 at 11:28 AM, Thomas Smyth wrote:

Yeah. My understanding of basic auth is that it does not use cookies.
It sends the base 64 encoded credentials with every request in the
headers. Without preemptive support, the httpclient is not even
consulting the httpcontext until it gets a 401, and this is so for
every request. That's why every request is doubled.

So perhaps you could test what I've done with a server running digest
auth (I don't have one). All I know is it's working beautifully on our
system, which is HTTPS, basic auth.

On 28 July 2011 14:16, Mitch Sundt msundt@cs.washington.edu wrote:

Ah, OK.

My understanding of the typical server-side implementation of form-based
authentication is that after the authentication, the server would use a
cookie to maintain the identity of the user, and only when the cookie is
missing would you re-auth; I had thought basic authentication would work
the
same way; if not, we'd clearly want the preemptive patch in for basic
authentication support.

ODK Collect is reusing the request context across calls so it will honor
and
return cookies that the server establishes (can't do digest auth without
that).

Mitch

On Thu, Jul 28, 2011 at 10:58 AM, Thomas Smyth thomas.smyth@gatech.edu wrote:

Does your server handle HEAD requests?

Yes.

If your server supports HEAD requests, the authentication negotiation
will
occur on the HEAD request. So you're not saving much by the
preemptive
authentication (it doesn't hurt anything, but it isn't a big win with
a
HEAD
request).

Actually in 1.1.7RC1, the authentication negotiation (Basic auth, this
is) is occurring on EVERY request. So every request is doubled. Unless
I'm mistaken, this is how non-preemptive basic authentication works.
With the code I've added in that patch, only the HEAD request happens
twice. So this is quite a big savings as the phone is not submitting
all the data twice.

Also due to another bug fixed in that patch, the app was actually
doing 3 POST requests. So the patch brings it from from 6 requests
total to 3, for Basic auth.

Please note that with basic auth, you should
require HTTPS for all interactions between ODK Collect and your server

Yes we're doing this. We need HTTPS anyway since all transmissions
need to be secure. That's why we decided to use basic auth as it was
easier to implement on the server side.

I am not sure if the code I have submitted would interfere with Digest
auth but I don't believe it would. Is that not what the AuthScope
mechanism is for?

Anyway you're free to use this patch or not. I am just happy that
things are working for my deployment. Thanks for your help.

--
Mitch Sundt
Software Engineer
http://www.OpenDataKit.org
University of Washington
mitchellsundt@gmail.com

--
Mitch Sundt
Software Engineer
http://www.OpenDataKit.org
University of Washington
mitchellsundt@gmail.com

I think that's what the AuthScope is for. But sure let's leave it to Carl :slight_smile:

In the meantime, the Sending screen and extraneous POST bugs should be
fixed before 1.1.7 is released IMHO as they are both bugs, where as
preemptive auth is an ehancement. I have attached the patches as
separate files to the appropriate issues in the issue tracker.

··· On 28 July 2011 14:35, Mitch Sundt wrote: > The patch should probably be changed to do preemptive auth only if the > target host port is 8443 or 443; what we really want to do is only send > credentials if the intended scheme is https, but I don't know how to do > that. > > Anyway, that's Carl's business... > > Mitch > > On Thu, Jul 28, 2011 at 11:28 AM, Thomas Smyth wrote: >> >> Yeah. My understanding of basic auth is that it does not use cookies. >> It sends the base 64 encoded credentials with every request in the >> headers. Without preemptive support, the httpclient is not even >> consulting the httpcontext until it gets a 401, and this is so for >> every request. That's why every request is doubled. >> >> So perhaps you could test what I've done with a server running digest >> auth (I don't have one). All I know is it's working beautifully on our >> system, which is HTTPS, basic auth. >> >> >> On 28 July 2011 14:16, Mitch Sundt wrote: >> > Ah, OK. >> > >> > My understanding of the typical server-side implementation of form-based >> > authentication is that after the authentication, the server would use a >> > cookie to maintain the identity of the user, and only when the cookie is >> > missing would you re-auth; I had thought basic authentication would work >> > the >> > same way; if not, we'd clearly want the preemptive patch in for basic >> > authentication support. >> > >> > ODK Collect is reusing the request context across calls so it will honor >> > and >> > return cookies that the server establishes (can't do digest auth without >> > that). >> > >> > Mitch >> > >> > On Thu, Jul 28, 2011 at 10:58 AM, Thomas Smyth wrote: >> >> >> >> > Does your server handle HEAD requests? >> >> >> >> Yes. >> >> >> >> > If your server supports HEAD requests, the authentication negotiation >> >> > will >> >> > occur on the HEAD request. So you're not saving much by the >> >> > preemptive >> >> > authentication (it doesn't hurt anything, but it isn't a big win with >> >> > a >> >> > HEAD >> >> > request). >> >> >> >> Actually in 1.1.7RC1, the authentication negotiation (Basic auth, this >> >> is) is occurring on EVERY request. So every request is doubled. Unless >> >> I'm mistaken, this is how non-preemptive basic authentication works. >> >> With the code I've added in that patch, only the HEAD request happens >> >> twice. So this is quite a big savings as the phone is not submitting >> >> all the data twice. >> >> >> >> Also due to another bug fixed in that patch, the app was actually >> >> doing *3* POST requests. So the patch brings it from from 6 requests >> >> total to 3, for Basic auth. >> >> >> >> > Please note that with basic auth, you should >> >> > require HTTPS for all interactions between ODK Collect and your >> >> > server >> >> >> >> Yes we're doing this. We need HTTPS anyway since all transmissions >> >> need to be secure. That's why we decided to use basic auth as it was >> >> easier to implement on the server side. >> >> >> >> I am not sure if the code I have submitted would interfere with Digest >> >> auth but I don't believe it would. Is that not what the AuthScope >> >> mechanism is for? >> >> >> >> Anyway you're free to use this patch or not. I am just happy that >> >> things are working for my deployment. Thanks for your help. >> > >> > >> > >> > -- >> > Mitch Sundt >> > Software Engineer >> > http://www.OpenDataKit.org >> > University of Washington >> > mitchellsundt@gmail.com >> > > > > > -- > Mitch Sundt > Software Engineer > http://www.OpenDataKit.org > University of Washington > mitchellsundt@gmail.com >