Re: Fetch: HTTP authentication and CORS

2013-05-08 Thread Paul Libbrecht
On 7 mai 2013, at 02:23, HU, BIN wrote:
 Because nonce is needed to generate the appropriate digest, the 401 
 challenge is required.

So the lesson here is: any developer that intends to use authenticated XHR 
should always start with an XHR that is a simple ping-like GET, then do the 
real things. Right?

Paul

RE: Fetch: HTTP authentication and CORS

2013-05-08 Thread HU, BIN
That is correct.

Thanks
Bin

From: Paul Libbrecht [mailto:p...@hoplahup.net]
Sent: Wednesday, May 08, 2013 1:14 PM
To: HU, BIN
Cc: Hallvord Reiar Michaelsen Steen; Jonas Sicking; Anne van Kesteren; WebApps 
WG; WebAppSec WG
Subject: Re: Fetch: HTTP authentication and CORS

On 7 mai 2013, at 02:23, HU, BIN wrote:
Because nonce is needed to generate the appropriate digest, the 401 challenge 
is required.


So the lesson here is: any developer that intends to use authenticated XHR 
should always start with an XHR that is a simple ping-like GET, then do the 
real things. Right?

Paul


Re: Fetch: HTTP authentication and CORS

2013-05-06 Thread Hallvord Reiar Michaelsen Steen
 I had a discussion with Hallvord on IRC about the exact semantics we
 want for HTTP authentication in the context of CORS (and in particular
 for XMLHttpRequest, though it would also affect e.g. img
 crossorigin).



So me and Anne have been going a bit back and forth on IRC, we agree on some 
stuff and disagree on other points - and we fundamentally agree that some 
implementor review and input would be valuable to really settle a conclusion on 
how this murky little intersection of specs should work..


So the basic issue is HTTP authentication (cached and/or supplied by JS) with 
XHR, and its interaction with CORS and other stuff like the anonymous flag and 
withCredentials.

 Username/password can be passed via open() or the URL. In that case we
 first check if the server challenges us (do a request without

 Authorization that results in a response with status 401).


So far I agree :)


 For CORS, we'd return to the caller right there.



Here I don't agree anymore. If I want to retrieve a HTTP auth-protected 
resource with XHR from a CORS-enabled server, the natural thing to do seems to 
try to pass in the user name and password in the XHR open() call. If the script 
author supplied user/pass and the server says 401 on a request without 
Authorization: surely the natural next step is to re-try with Authorization:?


Granted, my scenario takes a little bit more work before we reach this point: I 
think that if user/pass are supplied in open() or URL for a CORS request, the 
implementation must detect that the request requires preflight, and send 
Access-Control-Request-Headers: Authorization as part of that preflight.


Now, this is most definitely a corner case, me an Anne are both concerned about 
implementation complexity but we seem to draw different conclusions - I think 
that most of the infrastructure here is going to be in place already and making 
special XHR-CORS exceptions might be just as complex as implementing 
retry-with-Authorization, whereas I believe Anne thinks I'm prescribing too 
much complexity for too little gain. 
 
 If the Authorization header is set via setRequestHeader() we'd treat
 it as any other header. We assume the developer already checked if he
 was challenged or not, etc.



I agree with that :)
 
 If an Authorization header was cached for the URL in question

 (previous visit) we'd never reuse that under CORS.


This *might* be a case for withCredentials - but it doesn't make much sense 
given that a JS author can't be expected to know if there are cached 
credentials for some other site, so we've dropped that. However, most browsers 
prompt for user/pass if XHR (or IMG) requests are challenged - so we need a 
loophole that make sure the cached credentials from a request *triggered by* 
XHR *are* used (this is one place that gets overly complex - I'd definitely 
love to nuke the whole prompts-for-user/pass in response to JS/inlines 
misfeature. Anyone else agrees we can kill it without too much compat pain..?)
 I'd be great to know if there's consensus on this. General not caring works 
 too.



Implementor views most welcome, including I don't really care, either way 
works for us :-)



BTW, here's a sort of (amateur) flow chart for what I'm proposing - after 
accepting some of Anne's feedback:
https://www.w3.org/Bugs/Public/attachment.cgi?id=1359


I just noticed I have omitted same-origin requests with anonymous flag set - if 
these get a 401 response we should probably go straight to Done, content 
denied.

-- 
Hallvord R. M. Steen
Core tester, Opera Software








Re: Fetch: HTTP authentication and CORS

2013-05-06 Thread Jonas Sicking
On Mon, May 6, 2013 at 10:45 AM, Hallvord Reiar Michaelsen Steen
hallv...@opera.com wrote:
 I had a discussion with Hallvord on IRC about the exact semantics we
 want for HTTP authentication in the context of CORS (and in particular
 for XMLHttpRequest, though it would also affect e.g. img
 crossorigin).

 So me and Anne have been going a bit back and forth on IRC, we agree on some 
 stuff and disagree on other points - and we fundamentally agree that some 
 implementor review and input would be valuable to really settle a conclusion 
 on how this murky little intersection of specs should work..

 So the basic issue is HTTP authentication (cached and/or supplied by JS) with 
 XHR, and its interaction with CORS and other stuff like the anonymous flag 
 and withCredentials.

 Username/password can be passed via open() or the URL. In that case we
 first check if the server challenges us (do a request without

 Authorization that results in a response with status 401).


 So far I agree :)


 For CORS, we'd return to the caller right there.

 Here I don't agree anymore. If I want to retrieve a HTTP auth-protected 
 resource with XHR from a CORS-enabled server, the natural thing to do seems 
 to try to pass in the user name and password in the XHR open() call. If the 
 script author supplied user/pass and the server says 401 on a request without 
 Authorization: surely the natural next step is to re-try with Authorization:?

If the caller to the XHR.open() call provided a username and password,
then shouldn't the implementation send that information in the *first*
request rather than waiting for a 401?

Well.. first request after having done a preflight which checks that
the server is ok with an Authorization header being specified?

/ Jonas



Re: Re: Fetch: HTTP authentication and CORS

2013-05-06 Thread Hallvord Reiar Michaelsen Steen

 Here I don't agree anymore. If I want to retrieve a HTTP auth-protected 
 resource
 with XHR from a CORS-enabled server, the natural thing to do seems to try to 
 pass
 in the user name and password in the XHR open() call. If the script author 
 supplied
 user/pass and the server says 401 on a request without Authorization: surely 
 the
 natural next step is to re-try with Authorization:?
 
 If the caller to the XHR.open() call provided a username and password,
 then shouldn't the implementation send that information in the *first*
 request rather than waiting for a 401?



I'd like to do that, but Anne thinks it violates the HTTP protocol (and 
apparently is hard to implement on top of certain networking libraries?).


Any networking devs who would like to comment on that?

-- 
Hallvord R. M. Steen
Core tester, Opera Software








Re: Re: Re: Fetch: HTTP authentication and CORS

2013-05-06 Thread Hallvord Reiar Michaelsen Steen
  Here I don't agree anymore. If I want to retrieve a HTTP auth-protected 
  resource
  with XHR from a CORS-enabled server, the natural thing to do seems to try 
  to pass
  in the user name and password in the XHR open() call. If the script author 
  supplied
  user/pass and the server says 401 on a request without Authorization: 
  surely the
  natural next step is to re-try with Authorization:?
  
  If the caller to the XHR.open() call provided a username and password,
  then shouldn't the implementation send that information in the *first*
  request rather than waiting for a 401?
  

 I'd like to do that, but Anne thinks it violates the HTTP protocol


Replying to self, this would break the authentication method negotiation that 
HTTP allows (i.e. selection of basic, digest, and more proprietary stuff like 
NTLM). Hence we should wait for a 401 challenge. 


(Could we however fix this in CORS so that the WWW-Authenticate header could be 
included in a preflight response where applicable?)

-- 
Hallvord R. M. Steen
Core tester, Opera Software








Re: Re: Re: Fetch: HTTP authentication and CORS

2013-05-06 Thread Anne van Kesteren
On Mon, May 6, 2013 at 1:39 PM, Hallvord Reiar Michaelsen Steen
hallv...@opera.com wrote:
 (Could we however fix this in CORS so that the WWW-Authenticate header could 
 be included in a preflight response where applicable?)

Maybe we should wait for actual complaints about XMLHttpRequest + CORS
lacking integrated support for HTTP authentication before complicating
the protocol even more with unused garbage. In other words, given that
the majority of sites are not using a variant of HTTP authentication
at the moment I don't think further enshrining it is worth the cost.


--
http://annevankesteren.nl/



RE: Re: Fetch: HTTP authentication and CORS

2013-05-06 Thread HU, BIN
If we are talking about RFC2617 HTTP Authentication, there are 2 authentication 
models:

(1) Basic Authentication model:

Under this circumstance, basically client can send the username:password pair 
at the first request, e.g. in the form:

https://username:passw...@www.example.com/path

which in turn maps to an HTTP header

Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

Where username:password is BASE64-encoded.

Because of the vulnerability of Basic Authentication model (without 
encryption), https is strongly recommended.

But in practice, Basic Authentication is rarely used, and it is mostly based on 
a challenge-response model, where the server challenges with 401 code, and a 
Authentication header to ask for Basic Authentication:

WWW-Authenticate: Basic realm=WallyWorld

(2) Digest Authentication model:

Digest scheme is always based on challenge-response, and server challenges with 
401 code, Authentication heade, and other important information such as nonce, 
e.g.:

 HTTP/1.1 401 Unauthorized
 WWW-Authenticate: Digest
 realm=testre...@host.com,
 qop=auth,auth-int,
 nonce=dcd98b7102dd2f0e8b11d0f600bfb0c093,
 opaque=5ccc069c403ebaf9f0171e9517f40e41

so that client can apply the appropriate digest algorithm, such as MD5, and 
generate the response:

 Authorization: Digest username=Mufasa,
 realm=testre...@host.com,
 nonce=dcd98b7102dd2f0e8b11d0f600bfb0c093,
 uri=/dir/index.html,
 qop=auth,
 nc=0001,
 cnonce=0a4f113b,
 response=6629fae49393a05397450978507c4ef1,
 opaque=5ccc069c403ebaf9f0171e9517f40e41

Because nonce is needed to generate the appropriate digest, the 401 challenge 
is required.

Hope it helps

Bin

-Original Message-
From: Hallvord Reiar Michaelsen Steen [mailto:hallv...@opera.com] 
Sent: Monday, May 06, 2013 11:13 AM
To: Jonas Sicking
Cc: Anne van Kesteren; WebApps WG; WebAppSec WG
Subject: Re: Re: Fetch: HTTP authentication and CORS


 Here I don't agree anymore. If I want to retrieve a HTTP auth-protected 
 resource
 with XHR from a CORS-enabled server, the natural thing to do seems to try to 
 pass
 in the user name and password in the XHR open() call. If the script author 
 supplied
 user/pass and the server says 401 on a request without Authorization: surely 
 the
 natural next step is to re-try with Authorization:?
 
 If the caller to the XHR.open() call provided a username and password,
 then shouldn't the implementation send that information in the *first*
 request rather than waiting for a 401?



I'd like to do that, but Anne thinks it violates the HTTP protocol (and 
apparently is hard to implement on top of certain networking libraries?).


Any networking devs who would like to comment on that?

-- 
Hallvord R. M. Steen
Core tester, Opera Software








Re: Fetch: HTTP authentication and CORS

2013-05-04 Thread Anne van Kesteren
On Fri, May 3, 2013 at 7:00 PM, Jonas Sicking jo...@sicking.cc wrote:
 In the Gecko implementation they aren't. Assuming that you mean when with
 credentials is set to false?

Right, when it's set to false. What's the normative reference for TLS
client certificates? https://tools.ietf.org/html/rfc5246#section-7.4.6
maybe?


 We also don't reuse keep-alive http connections.

Are we talking about persistent connections as per
http://tools.ietf.org/html/rfc2616#section-8.1 or the obsolete
HTTP/1.0 feature?


--
http://annevankesteren.nl/



Re: Fetch: HTTP authentication and CORS

2013-05-04 Thread Jonas Sicking
On May 4, 2013 1:29 AM, Anne van Kesteren ann...@annevk.nl wrote:

 On Fri, May 3, 2013 at 7:00 PM, Jonas Sicking jo...@sicking.cc wrote:
  In the Gecko implementation they aren't. Assuming that you mean when
with
  credentials is set to false?

 Right, when it's set to false. What's the normative reference for TLS
 client certificates? https://tools.ietf.org/html/rfc5246#section-7.4.6
 maybe?


  We also don't reuse keep-alive http connections.

 Are we talking about persistent connections as per
 http://tools.ietf.org/html/rfc2616#section-8.1 or the obsolete
 HTTP/1.0 feature?

In the sense of the keep-alive header. I'm not sure, but I think it was
defined in HTTP 1.1.

/ Jonas


Re: Fetch: HTTP authentication and CORS

2013-05-04 Thread Bjoern Hoehrmann
* Jonas Sicking wrote:
On May 4, 2013 1:29 AM, Anne van Kesteren ann...@annevk.nl wrote:
 On Fri, May 3, 2013 at 7:00 PM, Jonas Sicking jo...@sicking.cc wrote:
  We also don't reuse keep-alive http connections.

 Are we talking about persistent connections as per
 http://tools.ietf.org/html/rfc2616#section-8.1 or the obsolete
 HTTP/1.0 feature?

In the sense of the keep-alive header. I'm not sure, but I think it was
defined in HTTP 1.1.

It's extremely unlikely that the `Keep-Alive` header is special here.
It rather seems to me you meant We also don't reuse http connections.
A HTTP connection has to be persistent, has to be kept alive, in order
for it to be re-used, and how or why a connection is kept alive does,
most probably, not affect whether Firefox will re-use it in your sense
above. And no, HTTP/1.1 as defined in RFC 2616 does not use the `Keep-
Alive` header.
-- 
Björn Höhrmann · mailto:bjo...@hoehrmann.de · http://bjoern.hoehrmann.de
Am Badedeich 7 · Telefon: +49(0)160/4415681 · http://www.bjoernsworld.de
25899 Dagebüll · PGP Pub. KeyID: 0xA4357E78 · http://www.websitedev.de/ 



Re: Fetch: HTTP authentication and CORS

2013-05-04 Thread Jonas Sicking
I really don't know which spec is defining how/when we reuse http
connections. All I know is that we have a pool of open TCP connections
that were used for previous http requests. We don't use that pool when
making credential-less CORS requests. We instead use a separate pool,
specifically for credential-less CORS requests.

Sorry I can't be more precise. I'm happy to point people to the
relevant code if needed.

/ Jonas

On Sat, May 4, 2013 at 3:58 PM, Bjoern Hoehrmann derhoe...@gmx.net wrote:
 * Jonas Sicking wrote:
On May 4, 2013 1:29 AM, Anne van Kesteren ann...@annevk.nl wrote:
 On Fri, May 3, 2013 at 7:00 PM, Jonas Sicking jo...@sicking.cc wrote:
  We also don't reuse keep-alive http connections.

 Are we talking about persistent connections as per
 http://tools.ietf.org/html/rfc2616#section-8.1 or the obsolete
 HTTP/1.0 feature?

In the sense of the keep-alive header. I'm not sure, but I think it was
defined in HTTP 1.1.

 It's extremely unlikely that the `Keep-Alive` header is special here.
 It rather seems to me you meant We also don't reuse http connections.
 A HTTP connection has to be persistent, has to be kept alive, in order
 for it to be re-used, and how or why a connection is kept alive does,
 most probably, not affect whether Firefox will re-use it in your sense
 above. And no, HTTP/1.1 as defined in RFC 2616 does not use the `Keep-
 Alive` header.
 --
 Björn Höhrmann · mailto:bjo...@hoehrmann.de · http://bjoern.hoehrmann.de
 Am Badedeich 7 · Telefon: +49(0)160/4415681 · http://www.bjoernsworld.de
 25899 Dagebüll · PGP Pub. KeyID: 0xA4357E78 · http://www.websitedev.de/



Re: Fetch: HTTP authentication and CORS

2013-05-03 Thread Jonas Sicking
In the Gecko implementation they aren't. Assuming that you mean when with
credentials is set to false?

We also don't reuse keep-alive http connections.

/ Jonas
On May 3, 2013 10:34 AM, Adam Barth w...@adambarth.com wrote:

 How does withCredentials interact with TLS client certificates?  Ideally
 they wouldn't be used either.

 Adam


 On Friday, May 3, 2013, Anne van Kesteren wrote:

 I had a discussion with Hallvord on IRC about the exact semantics we
 want for HTTP authentication in the context of CORS (and in particular
 for XMLHttpRequest, though it would also affect e.g. img
 crossorigin).

 Username/password can be passed via open() or the URL. In that case we
 first check if the server challenges us (do a request without
 Authorization that results in a response with status 401). For CORS,
 we'd return to the caller right there.

 If the Authorization header is set via setRequestHeader() we'd treat
 it as any other header. We assume the developer already checked if he
 was challenged or not, etc.

 If an Authorization header was cached for the URL in question
 (previous visit) we'd never reuse that under CORS.

 This means that withCredentials effectively means with cookies (and
 we should have called it that, mea culpa).

 I'd be great to know if there's consensus on this. General not caring
 works too.

 Context: http://krijnhoetmer.nl/irc-logs/whatwg/20130503#l-318 and
 onwards.


 --
 http://annevankesteren.nl/