Bob DeRemer wrote:

-----Original Message-----
From: Bob DeRemer [mailto:bob.dere...@thingworx.com]
Sent: Monday, September 09, 2013 1:30 PM
To: Tomcat Users List
Subject: RE: how to access HTTP response from jsr-356
ServerEndpointConfig.Configurator.modifyHandshake?



-----Original Message-----
From: Niki Dokovski [mailto:nick...@gmail.com]
Sent: Monday, September 09, 2013 1:11 PM
To: Tomcat Users List
Subject: Re: how to access HTTP response from jsr-356
ServerEndpointConfig.Configurator.modifyHandshake?

On Mon, Sep 9, 2013 at 5:26 PM, Bob DeRemer
<bob.dere...@thingworx.com>wrote:

 Thanks for the direction on using the respective Client/Server
EndpointConfig.Configurator plumbing to do a pre-connection AUTH.
Unfortunately, I'm stuck on the server side when trying to actually
modify the HTTP response result code from within the Configurator.
It doesn't appear that the HandshakeResponse [or anything else that
I could see] provides access to modify the actual HTTP response -
setting it to
403 if
the AUTH fails.    In fact, from looking at the UpgradeUtil.doUpgrade, it
seems that the decision to upgrade has already been made by the time
the modifyHandshake override gets called.

Yes the decision is'already made at that point. In this version of the
spec and current implementation, the only place to actully provide
different status code (aka 403) is when checkOrigin returns false.
http://docs.oracle.com/javaee/7/api/javax/websocket/server/ServerEndpo
intC
onfig.Configurator.html#checkOrigin(java.lang.String)

I don't know wether this works in your case, but for sure the next
spec revision could try to provide more application control in
"modifyHandshake"
checkOrigin would work if there was some way to gain access to the client
supplied headers.  Is there any way for my checkOrigin method to get access to
the calling request and associated HTTP headers?  If not, then I'm not sure how
to perform a pre-connected AUTH check based on the current implementation.

if there are any other suggestions, please LMK; meanwhile, I'll keep digging to
see if there's another solution.

Thx,bob


After looking at the options available and going through the websocket protocol specification again, I've found a better solution for authenticating using a JSR-356 implementation than the original concept of using ServerEndpointConfig.Configurator.modifyHandshake. The new approach still uses custom Client and Server EndpointConfig/Configurator instances to pass security information during the handshake, but instead of rejecting the handshake, it's cleaner to grab the security information in the OnOpen (from the ServerEndpointConfig) of the actual endpoint. At this point, simply perform whatever AAA you wish - calling close with an appropriate CloseReason if AAA fails.
With regard to DOS and opening websocket connections:

The websocket protocol already prohibits multiple clients from being in the 
connecting/handshake phase at once, which already helps reduce the DOS surface 
area.  In addition, the client and/or server side implementations can add 
additional logic to prohibit the number of concurrent connections from the same 
client endpoint based on configuration.

And, yes, once I get it done and tested, I'll write this up.


Hi.
I have been watching this a bit from the outside, and I am neither a Java nor a Tomcat nor a websocket expert. But I am wondering a bit if we are not here missing the forest for the trees, in the following sense :
If I understand correctly the issue at hand, it would be about
1) preventing DoS attacks by "protecting" the websocket interface by a prior 
AAA phase
2) how to do this AAA phase

When I read through the JSR-356, it looks to me more concerned about what happens while the websocket connection is actually open, than about what precedes it. And when I read the websocket RFC-6455, it seems to me that at least in terms of the intent, the websocket connection is established - from the server point of view - when the server returns a 101 response status. And anything before that is part of the "initial handshake", which as far as I understand it is purely HTTP and includes anything to do with AAA.

See RFC-6455 :

4.  Opening Handshake
4.1.  Client Requirements
...
   12.  The request MAY include any other header fields, for example,
        cookies [RFC6265] and/or authentication-related header fields
        such as the |Authorization| header field [RFC2616], which are
        processed according to documents that define them.

   Once the client's opening handshake has been sent, the client MUST
   wait for a response from the server before sending any further data.
   The client MUST validate the server's response as follows:

   1.  If the status code received from the server is not 101, the
       client handles the response per HTTP [RFC2616] procedures.  In
       particular, the client might perform authentication if it
       receives a 401 status code; the server might redirect the client
       using a 3xx status code (but clients are not required to follow
       them), etc.  Otherwise, proceed as follows.

...

In JSR-356, there is similarly :

8.1 Authentication of Websockets
This specification does not define a mechanism by which websockets themselves can be authenticated. Rather, by building on the servlet defined security mechanism, a websocket that requires authentication must rely on the opening handshake request that seeks to initiate a connection to be previously authenticated. Typically, this will be performed by a Http authentication (perhaps basic or form-based) in the web application containing the websocket prior to the opening handshake to the websocket.

In other words, I am a bit confused as to why there would need to be a need for any websocket application to be able to either access the client-sent authentication headers, cookies etc.., or why it should be possible to the websocket application to trigger the sending of a HTTP 4xx response.

This should all already have happened at the initial HTTP handshake phase, and should not be a concern for the websocket interface itself. It may be nice for the websocket application later on to have read access to the (or some) headers sent by the client during the initial handshake, but this does not look like a requirement.

Or am I in turn missing something ?


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to