Subject: Re: [hybi] Supporting OAUTH-like authentication?

From: Brian <[email-masked]>
Date: Fri, 12 Aug 2011 13:30:06 -0700

This seems like a discussion for the JS API to me.  The protocol spec
already explicitly allows arbitrary HTTP headers to be both sent and
received by the WebSocket server and client, if I recall correctly.  The
only thing preventing usage of this feature is a limitation in the
JavaScript API.  I don't think there's any reason to disallow arbitrary
headers being set on the WS handshake using exactly the same
mechanism/restrictions as we do today for XHR.  But what does that have to
do with HyBi?

Brian

On Thu, Jul 28, 2011 at 6:34 PM, Greg Wilkins <[email-masked]> wrote:

> Philipp,
>
> Doing the auth within the connection is certainly possible, maybe even
> desirable.  However, I think that there could be a concern about not
> wanting to accept connections from non-authenticated sources, as to do
> so already represents an allocation of resources.    There are also
> extra RTT's involved in token exchange after the handshake.
>
> So failing giving access to HTTP headers, doing oauth the "normal" way
> in headers in the handshake will not be possible.    Those wanting
> authentication in the handshake can probably kludge it now using the
> protocol string.      So do we want to better facilitate auth in the
> handshake.
>
> Note also, that with your counter example, there are probably things
> we could do to make it more elegant.  For instance, perhaps we want to
> allow multiple sub-protocols so we don't have to come up with
> "foo+oauth", "bar+oauth" etc and instead just negotiate "oauth,foo"
>
> Eitherway, I think we need to step through (probably implement), some
> common authentication mechanisms to see how they work with the current
> protocol and to see how we can improve support for them.
>
> cheers
>
>
>
>
> On 29 July 2011 11:00, Philipp Serafin <[email-masked]> wrote:
> > Wouldn't it be better to move the token exchange into the actual WS
> > connection where we have efficient two-way communication available?
> >
> > 1.: Client connects to server using subprotocol "foo", which is known to
> > use OAuth as authentication (or e.g. "foo+oauth", if this should be
> > decided on per-connection basis)
> > 2.: Client and server perform successful WS handshake
> > 3.: Server sends token and authority URL in a WS message.
> > 4.: Client gets token authorized
> > 5.: Client sends authorized token back in a WS message.
> > 6.: Server confirms that authorisation was successful.
> > 7.: Client and server exchange messages as specified by "foo".
> >
> > Am 29.07.2011 02:44, schrieb Greg Wilkins:
> >> All,
> >>
> >> Currently the protocol allows arbitrary headers, so in theory an
> >> authentication mechanism like OAUTH could be implemented by exchanging
> >> tokens in the headers of the handshake.    But the js API does not
> >> allow an application to set or see HTTP header from the handshake (nor
> >> should it), so that is not available as a general mechanism for token
> >> passing auth like OAUTH.
> >>
> >> So what other options do we have to pass tokens in the handshake?
> >>
> >> Cookies - this is possible, but kind of defeats the purpose of  token
> >> passing auth if tokens are to be sent/set in a way that facilitates
> >> wider access to them.
> >>
> >> Extensions - we could say that an OAUTH extensions is required to
> >> manipulate the headers of the handshake with OAUTH tokens, but I
> >> expect that there will be a very high barrier for an extension to be
> >> included in browsers, so I think that is probably a non starter (at
> >> least until a defacto-standard auth mechanism emerges).
> >>
> >> Subprotocol/CloseEvents - Subprotocol is a user controlled field sent
> >> by the handshake and closeEvents contain a reason string that could
> >> originate from the server application/framework.     Thus I would not
> >> be surprised to see these fields used (misused?) to send challenges
> >> and pass tokens eg.
> >>
> >>  1. Client connects to server with oauth subprotocol.
> >>  2. Server accepts connection but immediately closes with a reason
> >> string containing a token and/or authority URL. ( might be able to be
> >> done with a 403 HTTP response if the HTTP reason string is passed to
> >> the onerror call back ?? ]
> >>  3. Client gets the token signed by an/the authority
> >>  4. Client connections to server with oauth;token=value subprotocol
> >>  5. Server validates authorisation of token and accepts connection.
> >>
> >> [ forgive me if that is not exactly how oauth works or correct
> >> terminology ... but it is something like that ]
> >>
> >> Is this a good usage of the subprotocol field/reason fields?
> >>
> >> Is there a better way to integrate such authentication into the
> handshake?
> >>
> >>
> >> cheers
> >> _______________________________________________
> >> hybi mailing list
> >> [email-masked]
> >> https://www.ietf.org/mailman/listinfo/hybi
> >
> >
> _______________________________________________
> hybi mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/hybi
>

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Sat, 13 Aug 2011 00:28:17 +0200

2011/8/12 Brian <[email-masked]>:
> mechanism/restrictions as we do today for XHR.

> But what does that have to do with HyBi?

This is like asking "what does Digest authentication have to do with
SIP protocol?", or "what does _XMPP_authentication_mechanism_ have to
do with XMPP protocol?".

Maybe you prefer to see WebSocket as a "transport" protocol, but it's
an application protocol, and it's not crazy *at all* to expect that an
application protocol implements an authentication mechanism. But
probably, given the ugly HTTP jungle, many people from HTTP world
assume that authentication must exist in user layer, based on ugly
HTML forms which require rendering a web page in the client.

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

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Sat, 13 Aug 2011 00:39:33 +0200

> decided on per-connection basis)

I don't like point 1 (due to same reason given by Greg in next mail).

> 7.: Client and server exchange messages as specified by "foo".

Let me propose another approach:

1.: Client connects to server using subprotocol "foo". Client does NOT
know which authentication the server requires (neither if the server
does require authentication or not). Please don't assume that a
specific WS subprotocol always requires the same authentication
mechanism. It's the server who must decide it at any time.

2.: Client and server perform successful WS handshake. The server
requires (in this case) Digest authentication so the 101 response
contains a *standard* header defined in WS core draft:

  Sec-WebSocket-Authenticate: Digest realm="domain.org",
     nonce="4e45a9e60000856cac2a6dd2e4edeba1a83e2ceb7137c3d0",
     qop="auth"

3.: Client supports Digest authentication so it taken the
username/passwd from somewhere (WS-API) and starts speaking
"auth+digest" WS subprotocol (which should be defined in some RFC).

4.: So client sends a WS message containing the computed Digest credentials.

5.: Server confirms that authorisation was successful in a WS reply.

6.: Client and server exchange messages as specified by subprotocol "foo".

Now replace Digest with OAUTH or whatever. Of course, all those
authentication mechanism should be standarized by different RFC's to
be used in WS. Each one would involve a defined WS subprotocol
("auth+digest", "auth+oauth").

A WS server could reply more than one Sec-WebSocket-Authenticate
header (one with "Digest" and another one with "OAUTH") in case it
supports both, so the client could choose which one to use.

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