Subject: [hybi] About authentication mechanism

From: Iñaki Baz Castillo <[email-masked]>
Date: Mon, 20 Jun 2011 14:01:36 +0200

Hi, I would like to start a new thread for this topic as it seems that
the draft does not cover it at all (just suggests that an HTTP
response code other than 101 should be threated as RFC 2616 states:

  "1.  If the status code received from the server is not 101, the
        client handles the response per HTTP procedures." (p. 30)

The question is: should the browser prompt the human user for
user/pass as when a 401 is received in the WS handshake attemp?

Imagine this case:

- www.domain.org => 1.1.1.1:80

- ws.domain.org => 1.1.1.2:443

- I open http://www.domain.org in my browser, fill some login form and
retrieve websocket connection data, including an user and pass (for
Digest).

- My JavaScript is then provisioned (via JavaScript WebSocket API
????) with ws connection data: server ip, port, Digest user/passwd.

- My web browser starts the ws connection with ws.domain.org:443. It
receives 401 with Digest (so I need a nonce from the server before
using my user/passwd).

- JavaScript code automatically accepts the Digest chanllenge,
generates a Digest response with the provided user/passwd and the
retrieved Digest nonce, and re-send the HTTP GET request (all of this
without prompting the user) with the Authorization header.

- If the JavaScript code would not be proviosioned with user/pass,
then upon receipt of the 401 it should prompt the user (like a
JavaScript alert?).

So, if all this stuff is not clearly specified (and I think passing
user/pass to the JavaScript WebSocket connection API does not exist)
then using HTTP Digest (or Basic) will be not useful or feasible, and
I expect than using cookies and all that "pure just-web stuff" will be
the only way. Please, take into account that a websocket server could
run in a separate server, so using cookies mechanism is not so
feasible (it could or not depending the case). Neither I think that
cookies (a workaround to simulate
sessions in HTTP protocol) are the best way to go.

IMHO the draft should do much more effort in authentication process.
Please don't let the door open to ugly and/or propietary
authentication solutions.

My proposal is that the JavaScript WebSocket API should include a
method to pass authentication 'user' and 'password' (and optionally
'realm' so it would ignore the realm para in the 401 response when
using Digest rather than Basic auth).

In this way, I could open a webpage, perform usual login (maybe via a
HTML form as commonly extended) and then retrieve WS connection data
(WS URI), including user/pass/[realm].
So my JavaScript client would open a WS connection with the given
destination and in case of receiving a 401 it would re-send the HTTP
GET request with the appropriate Authorization header without
prompting the user.

This wouldn't be the only authentication mechanism, of course, but
IMHO it should be documented (and covered by the JS WebSocket API).

Regards.

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Tue, 21 Jun 2011 15:43:05 +0200

Hi, any comment about this please? IMHO this topic is important. If
I'm wrong I would like to know it :)

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Greg Wilkins <[email-masked]>
Date: Wed, 22 Jun 2011 09:35:56 +1000

> I'm wrong I would like to know it :)

In many respects, this is a thread that should probably occur within
the W3C and WHATWG lists, as how browsers handle credential collection
is much more of an issue for them than the IETF..   Note that I think
they are in final call on their APIs as well.

It is true that the current version of the draft no longer denies the
ability of a client to handle 401 responses, so that is perhaps all
that we need.     However it might be that we should consider if we
recommend support for BASIC and DIGEST.

cheers

> _______________________________________________
> hybi mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/hybi
>

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Wed, 22 Jun 2011 02:01:17 +0200

> they are in final call on their APIs as well.

Yes, maybe. However, if WebSocket draft doesn't mandate support of
HTTP authentication, how could W3C mandate it?

> recommend support for BASIC and DIGEST.

I strongly recommend discarding BASIC and mandating just DIGEST. SIP
protocol also uses HTTP authentication (RFC 2617) but mandates DIGEST
and disallows BASIC (for obvious reasons):

RFC 3261 (SIP Protocol):

22 Usage of HTTP Authentication
   [...]
   Note that due to its weak security, the usage of "Basic"
   authentication has been deprecated.  Servers MUST NOT accept
   credentials using the "Basic" authorization scheme, and servers also
   MUST NOT challenge with "Basic".

Regards.

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Ian Fette (イアンフェッティ) <[email-masked]>
Date: Tue, 21 Jun 2011 17:04:32 -0700

Speaking as an individual,

I would not want to support this from the browser side. We finally are
starting to kill in browsers HTTP AUTH dialogs created by subresources
(images etc). Frankly it's a very poor user experience. I think most people
will use WS the way they use XHR + long polling, namely they will be on an
established page, do their authentication however they do their
authentication, set a cookie and move on. In some small corner of the
universe, a small set of applications may continue to use HTTP AUTH, but I
don't feel compelled to go out of the way to make its use any easier than if
I had requested javascript from another origin which popped up an auth
dialog. (Rather, I would probably block that as a browser).

-Ian

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Wed, 22 Jun 2011 02:20:37 +0200

> dialog. (Rather, I would probably block that as a browser).

So what about if the websocket server is not the same as the web
server from which the JS code has been got? Would the WS handshake
request include a Cookie header (that replied in the HTTP 200 OK from
the server? so, should the separate websocket server do some magic
with the Cookie value to verify ist validity?

Many web servers store the sessions data in memory so, which kind of
exotic mechanism should use the separate websocket server to validate
the given Cookie? use a shared database or shared memory (i.e.
memcached) for storing sessions?

Honestly I'm a bit afraid about your assumption in which clearly you
assume that the websocket server listens in the same host as the web
server. I strongly think that the protocol should define a well
specified and feasible authentication mechanism instead of assuming
that develovers will do some kind of magic in server side (a protocol
should not require that).

Regards.

PS: I agree that prompting the user with HTTP authentication dialog is
a pain, but I'm not suggesting that for websocket. In other thread I
explained how the JavaScript code retrieved by the browser (after user
login using whatever mechanism) could containg the WS URI connection
along with authentication information (i.e. user and pass for Digest
auth). Then the browser contacts the websocket server (don't assume
it's co-located with the web server), receives the 401 containing the
realm and nonce to use, and generates a new WS handshake request with
proper authentication credentials. This would prompt nothing to the
user.

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Ian Fette (イアンフェッティ) <[email-masked]>
Date: Tue, 21 Jun 2011 17:56:08 -0700

> with the Cookie value to verify ist validity?

How would you do it if you weren't using WebSockets but instead XHR? I doubt
you would use HTTP auth...

> server.

I'm not assuming they're on the same host. Certainly at Google that would
not be the case.

> I strongly think that the protocol should define a well

I agree that a better solution would be to do whatever authentication you
need when the user goes to the website, and then once the user is
authenticated open the WS connection and pass some sort of credential. That
could be via cookies if it's on the same origin, or it could be passed over
the established WS connection. I don't know that it should be defined in the
WS API though, as different sites might want to use vastly different
authentication mechanisms (client-side certs, passwords, oauth, ...). It's
much more flexible to leave it to the application.

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Wed, 22 Jun 2011 12:06:59 +0200

> you would use HTTP auth...

Usually XHR is sent to the same web server (so using Cookie is very
suitable), am I wrong?
Note however I'm not an expert in XHR so maybe I miss something.

> much more flexible to leave it to the application.

Ok, but take into account that not all the WS connections would be
preceded by an access to a web page. Let's imagine a desktop wigdet
(or an Android app!) that directly open a WS connection (without
opening first a web page, so the client cannot authenticate via an
HTML form in "any custom way"). What to do then? How to prompt the
user for credentials? which authentication mechanism to use? So there
would be needed:

- An API for promting the user for credentials.
- A specified authentication mechanism for "pure websocket" connection
(without depending on a previous HTTP/HTML access).

Have the WG considered this case?

IMHO authentication should occur at protocol level, rather than at
application level. This is true in all the protocols of Internet but
HTTP, which is a jungle. But HTTP usually means displaying a web page
with some HTML form in which the user can interact by setting his
credentials, press "submit" and that's all. Such kind of
authentication level is not possible in WebSocket as a WebSocket
renders nothing to the user, a WebSocket server does reply a web page.

I still see the need to mandate the support of HTTP Digest
authentication in WebSocket (which involves an API and a section in
current specification.

Regards.

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Wed, 22 Jun 2011 12:42:48 +0200

2011/6/22 Ian Fette (イアンフェッティ) <[email-masked]>:
> A desktop widget / android app / ... surely already faces this problem with
> whatever communication mechanism they use, and I would be frankly amazed if
> they expected to solve it with http auth...

So:

- Web developers don't like HTTP authentication in web pages and
prefer authentication at application level. I agree, it's nicer, but
it relies on the fact that HTTP usualy carries a web page (application
data) in which the user can fill a form, submit, and get
authentication and a Cookie for a session.

- This WG does not want to cover authentication mechanism at all for
WebSocket protocol, and instead leave it again at application level.
But here there is no a rendered web page in which the user can fill a
login form. So...

Assuming that any websocket connection would be preceded by a web
access (in which login and a session Cookie has been got) would be a
terrible error IMHO. So, does nobody agree that WS needs a built-in
authentication mechanism? Honestly I cannot understand. Hope I miss
something very important in this topic.

PS: Ian, could I know what you propose on this topic? For now you have
given reasons not to mandate HTTP auth. Could I know how will Google
authenticate WS connections in separate just-WS-servers? maybe
validating the Cookie header (initially retrieved from the web page)
against a centralized storage backend? or maybe you plan to build an
authentication mechanism within the WS carried subprotocol? (just
wondering, I don't want to know Google's internals).

Regards.

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Ian Fette (イアンフェッティ) <[email-masked]>
Date: Wed, 22 Jun 2011 03:21:43 -0700

> Note however I'm not an expert in XHR so maybe I miss something.
XHR can be sent to a different origin. http://www.w3.org/TR/cors/

---

From: John Tamplin <[email-masked]>
Date: Tue, 28 Jun 2011 17:57:43 -0400

> authentication and a Cookie for a session.

Note that cookies are problematic for supporting multiple tabs logged in
with different accounts, and are vulnerable to XSRF attacks without
additional precautions.

> something very important in this topic.

The point is common practice in web apps is not to use HTTP authentication
anyway (aside from not being able to style it the way you want, you can't
easily log out, plus other limitations), but to have the app request the
credentials and send them to the server itself.  If it takes that approach,
then it can easily do the same thing for WS communication.

-- 
John A. Tamplin
Software Engineer (GWT), Google

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Wed, 29 Jun 2011 00:19:55 +0200

> with different accounts, and are vulnerable to XSRF attacks without

But still Cookies are the only authentication mechanism mentioned in
the WS draft.

> easily log out, plus other limitations),

I agree. It's ugly.

> but to have the app request the

Humm, in my previous mail I already explained that a web server
returns an HTML page in which the user can fill his credentials and
so. But in WebSocket, how to do that? when you connect to a WebSocket
server you don't receive a custom HTML or a form to login.

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Ian Fette (イアンフェッティ) <[email-masked]>
Date: Tue, 28 Jun 2011 15:21:22 -0700

> server you don't receive a custom HTML or a form to login.
A user is not going to type in a ws:// url to a browser or other client.
They are going to open some webpage/application/... that will have ample
opportunity to deal with login before that thing instantiates the ws
connection.

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Wed, 29 Jun 2011 00:43:05 +0200

> opportunity to deal with login before that thing instantiates the ws

Ian, I think I already exposed the issue with your suggestion:

- Web Server:  1.1.1.1:80
- WebSocket Server:  2.2.2.2:80

The webbrowser gets a page and a JS code from 1.1.1.1:80.
The JS opens a WebSocket connection with 2.2.2.2:80.

Could you explain me how the WebSocket server, ***running in a
separate server***, can authenticate the user based on previous user's
authentication with the Web Server?

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Ian Fette (イアンフェッティ) <[email-masked]>
Date: Tue, 28 Jun 2011 15:44:49 -0700

> authentication with the Web Server?
Pass an oauth token, or have the WS server issue some challenge that the JS
answers (or presents to the user on behalf of the server if it's really
necessary), many ways. This is not a new problem.

---

From: Greg Wilkins <[email-masked]>
Date: Wed, 29 Jun 2011 09:03:39 +1000

> necessary), many ways. This is not a new problem.

It would be great if the oauth token could be in the handshake, so
that authentication (and thus authorisation) could be done before a WS
connection is established.
I would not be surprised if we see the subprotocol field used for this
purpose, as the only user settable header in the handshake.

cheers

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Wed, 29 Jun 2011 10:05:31 +0200

2011/6/29 Ian Fette (イアンフェッティ) <[email-masked]>:
> Pass an oauth token,

How? within the subprotocol itself?

> or have the WS server issue some challenge that the JS
> answers

Reinventing the wheel (HTTP Digest auth) but at WS subprotocol level?
So should the JavaScript client *code* perform the challenge in pure
and custom JavaScript code? I expect *lots* of future vulnerabilities
in WS.

Unfortunately it's common in this WG not to reuse existing
technologies (neither reusing DNS SRV for good
load-balancing/failover, neither reusing any existing authentication
mechanism). This is not good IMHO.

> (or presents to the user on behalf of the server if it's really

Even worse, it's not a new problem but it seems that WebSocket draft
authors don't want to deal with it. WebSocket world will become a
jungle.

So, is it really possible that WebSocket will be the first
client->server protocol without, at least, one solid authentication
mechanism specified? I just can't believe it. Please, WS is not like a
DNS query. WS is supposed to carry personal and private data.

Please don't take me wrong, but IMHO some other people with experience
in Internet protocols other than HTTP should also take a look to this
draft. I don't like the WWW-style of doing things this protocol is
acquiring. The fact that WWW world is a jungle doesn't mean that any
other new protocol (even when related to HTTP) should also be jungle.

I strongly disagree with the direction this draft is taking when
coming to authentication area in WebSocket protocol.

Regards.

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: John Tamplin <[email-masked]>
Date: Wed, 29 Jun 2011 04:28:26 -0400

> mechanism). This is not good IMHO.

How many sites use HTTP auth instead of rolling their own?  I can't think of
a single one that I use regularly that does.

Therefore, standardizing on something that nobody uses seems hardly a good
idea.  It also seems unlikely that everyone would agree on a the One True
Auth mechanism to be included in WS.  Personally, I would expect one or more
extensions to be created that specifies how credentials are sent in the
handshake, assuming there is sufficient interest and that a common standard
emerges, such as perhaps OAuth.

> authors don't want to deal with it. WebSocket world will become a

Make a proposal and see if you can get sufficient support behind it.  I am
pretty sure HTTP Auth is not going to achieve such support, and given how
long WS has taken to achieve consensus, I suspect any such mechanism will be
done via an extension.

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Wed, 29 Jun 2011 10:41:43 +0200

> a single one that I use regularly that does.

Hi John. Thanks for your response. Anyhow it seems I must repeat many
times the same in this same thread:

A web server returns an HTML page in which the user can fill his credentials and
so (a form). But in WebSocket, how to do that? when you connect to a WebSocket
server you don't receive a custom HTML or a form to login, instead you
recibe from the server some WS message containing a subprotocol
request (which is supposed to be custom in each subprotocol). How to
render that to the user?

> idea.

And since WWW is a jungle you are making a new jungle. There are many
protocols in which authentication is not a jungle, why not copy from
them instead of copying from WWW?

>  It also seems unlikely that everyone would agree on a the One True
> Auth mechanism to be included in WS.

IMHO the draft should specify at least one. Others could come into new
extensions to the draft (as in many other protocols as SIP or XMPP).

> Personally, I would expect one or more
> handshake,

But again, IMHO the core draft should already specify one.

> assuming there is sufficient interest

Interest in secure authentication? such interesnt should be mandatory.

> and that a common standard

There are already enough authentication mechanism not to need waiting
for a new one (IMHO).

> long WS has taken to achieve consensus, I suspect any such mechanism will be

I don't say that HTTP Auth is the best, it's just an option. WWW
people don't like it because, indeed, it's ugly implemented (the popup
alert, difficult to logout, etc). It does not mean that it could be
properly implemented in WebSocket if its done well from the beginning.

Regards.

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: John Tamplin <[email-masked]>
Date: Wed, 29 Jun 2011 04:47:23 -0400

> times the same in this same thread:

I feel the same way, and this is my last response.

> request (which is supposed to be custom in each subprotocol). How to

Some JS code is making a WS request.  It can use whatever mechanism it wants
for obtaining the credentials from the user, and send them over the WS
connection.

> them instead of copying from WWW?

Feel free to suggest something that has broad consensus.  I haven't heard
any such suggestion, nor have I heard anyone else beside you clamoring for
it.

---

From: Greg Wilkins <[email-masked]>
Date: Wed, 29 Jun 2011 19:14:33 +1000

> a single one that I use regularly that does.

It is true that not many (if any) large when known sites use the HTTP
auth mechanisms. However there are many many smaller sites that do use
them and they remain well supported by J2EE environments. I also
frequently see them used with webservices.

I really don't think that WS should be forcing a choice in
authentication mechanism.   It should be able to support:
  + standard HTTP authentication mechanisms
  + simple cookie based authentication
  + token passing (eg oath) authentication

I actually think the protocol already is pretty good at doing all
this, however the API does not support any of them.

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Wed, 29 Jun 2011 11:14:57 +0200

> I feel the same way, and this is my last response.

Mine also, I think this thread is long enough and opinions are already given.

> for obtaining the credentials from the user, and send them over the WS

Which means authentication at pure JavaScript level. Dangerous IMHO.

> any such suggestion, nor have I heard anyone else beside you clamoring for

This is expected as, IMHO, most of this WG comes from WWW world in
which no one authentication standard has succedeed (HTTP auth is ugly
indeed) so custom authentication mechanism are mainly used.

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Wed, 29 Jun 2011 11:16:03 +0200

> this, however the API does not support any of them.

So there is nothing then...

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Ian Fette (イアンフェッティ) <[email-masked]>
Date: Wed, 29 Jun 2011 19:28:36 -0700

> mechanism). This is not good IMHO.
I think the base protocol defines enough for the vast majority of people to
easily work this into their workflow. For those that it's nontrivial for,
it's certainly possible and by no means a hard CS problem. If enough people
face it, they can build a library, or propose an extension.

As for loadbalancing / failover beyond what basic DNS provides, again, this
isn't required for a base protocol but could easily be specified as an
extension should the need arise / people wish to do so. HTTP and TCP weren't
built in a day either.

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Thu, 30 Jun 2011 13:50:08 +0200

> extension should the need arise / people wish to do so. HTTP and TCP weren't

Hi Ian. DNS SRV does exist but however HTTP makes no usage of it, why?
because HTTP was previous to SRV and because at this time, it's
impossible to expect that all HTTP clients would implement SRV.

If WebSocket protocol is published without mandating DNS SRV
resolution in client side, then adding it into a late extension will
never succeed (as there will be clients not supporting it, so a server
could never rely on SRV resolution from clients).

In other protocols much more complex than WebSocket (as SIP or XMPP),
DNS SRV is defined/mandated in the core protocol, it's not an
extension, so things work.

BTW: http://tools.ietf.org/html/draft-ibc-websocket-dns-srv-02

Cheers.

-- 
Iñaki Baz Castillo
<[email-masked]>