Discussion:
solution - RE: how to access HTTP response from jsr-356 ServerEndpointConfig.Configurator.modifyHandshake?
Bob DeRemer
2013-09-09 20:46:23 UTC
Permalink
-----Original Message-----
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-----
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
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.

-bob
cheers
Niki
****
** **
If I'm missing anything, please let me know.****
** **
Thanks,****
** **
*Bob DeRemer*
*Senior Director, Architecture and Development*
** **
http://www.thingworx.com****
Skype: bob.deremer.thingworx****
O: 610.594.6200 x812****
M: 717.881.3986****
** **
---------------------------------------------------------------------
André Warnier
2013-09-10 10:11:47 UTC
Permalink
Post by Bob DeRemer
-----Original Message-----
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-----
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
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.
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 ?
Bob DeRemer
2013-09-10 12:56:26 UTC
Permalink
-----Original Message-----
Sent: Tuesday, September 10, 2013 6:12 AM
To: Tomcat Users List
Subject: Re: solution - RE: how to access HTTP response from jsr-356
ServerEndpointConfig.Configurator.modifyHandshake?
Post by Bob DeRemer
-----Original Message-----
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-----
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
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/ServerEnd
po
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.
Post by Bob DeRemer
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.
Post by Bob DeRemer
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.
Post by Bob DeRemer
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
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.
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.
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.
...
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 ?
Hi Andre,

I see what you mean and believe using an HTTP-based auth approach may work in some scenarios. I'm not sure if this would work in one of our primary scenarios, which is dealing with many real-world devices that do not have a UI, so basic/form authentication isn't an option. That said, I will have to see if I can use a standard Filter approach in front of our websocket endpoints. If I can programmatically add an auth filter, then I may be able to perform the auth check in the same manner as we do for our stand HTTP-based REST api.

Thx, bob
---------------------------------------------------------------------
Bob DeRemer
2013-09-10 14:35:08 UTC
Permalink
-----Original Message-----
Sent: Tuesday, September 10, 2013 8:56 AM
To: Tomcat Users List
Subject: RE: solution - RE: how to access HTTP response from jsr-356
ServerEndpointConfig.Configurator.modifyHandshake?
-----Original Message-----
Sent: Tuesday, September 10, 2013 6:12 AM
To: Tomcat Users List
Subject: Re: solution - RE: how to access HTTP response from jsr-356
ServerEndpointConfig.Configurator.modifyHandshake?
Post by Bob DeRemer
-----Original Message-----
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-----
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
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.
Post by Bob DeRemer
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/ServerE
nd
po
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.
Post by Bob DeRemer
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.
Post by Bob DeRemer
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.
Post by Bob DeRemer
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
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.
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.
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.
...
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 ?
Hi Andre,
I see what you mean and believe using an HTTP-based auth approach may work
in some scenarios. I'm not sure if this would work in one of our primary
scenarios, which is dealing with many real-world devices that do not have a UI,
so basic/form authentication isn't an option. That said, I will have to see if I can
use a standard Filter approach in front of our websocket endpoints. If I can
programmatically add an auth filter, then I may be able to perform the auth
check in the same manner as we do for our stand HTTP-based REST api.
Thx, bob
It appears I can call addFilter dynamically when my webapp starts up and front-end the websocket endpoint with a Filter - processing the initial HTTP request completely before any websocket communication is involved

Thanks for causing me to pull up from the weeds and look at this from another angle!

-bob
---------------------------------------------------------------------
---------------------------------------------------------------------
Christopher Schultz
2013-09-10 16:06:49 UTC
Permalink
Bob,
Post by Bob DeRemer
It appears I can call addFilter dynamically when my webapp starts
up and front-end the websocket endpoint with a Filter - processing
the initial HTTP request completely before any websocket
communication is involved
This was kind of what I was expecting to work.

But why do you have to add the Filter programmatically? Is this a
component that you just want to bolt-onto an existing webapp and you
don't want to mess with web.xml and/or web-fragments?
Post by Bob DeRemer
Thanks for causing me to pull up from the weeds and look at this from another angle!
- -chris
Bob DeRemer
2013-09-10 17:34:51 UTC
Permalink
-----Original Message-----
Sent: Tuesday, September 10, 2013 12:07 PM
To: Tomcat Users List
Subject: Re: solution - RE: how to access HTTP response from jsr-356
ServerEndpointConfig.Configurator.modifyHandshake?
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Bob,
Post by Bob DeRemer
It appears I can call addFilter dynamically when my webapp starts up
and front-end the websocket endpoint with a Filter - processing the
initial HTTP request completely before any websocket communication is
involved
This was kind of what I was expecting to work.
But why do you have to add the Filter programmatically? Is this a component
that you just want to bolt-onto an existing webapp and you don't want to mess
with web.xml and/or web-fragments?
It's actually a new application, but I wanted to add this programmatically because we're running off of our own configuration that will enable/disable certain functionality (i.e. endpoints/servlets/other components) based on that configuration.

So, a combination of our own requirements plus not wanting to work with web.xml/web-fragments.
Post by Bob DeRemer
Thanks for causing me to pull up from the weeds and look at this from another angle!
- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.14 (Darwin)
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/
iQIcBAEBCAAGBQJSL0OZAAoJEBzwKT+lPKRYM7UP/2zdUaDr6LHE3onxUnRZ5jM
/
DptjeReE7nuLyqxINUlEF828XEfpZVlBS325Xfd8E13mB7bUg+aNGK2jjIsyhfjr
B+tUBp0Ur52Dg5PDGPV6Qt4Obi8eg3766TQxleZU6ui3dWdLz5PdMeeSb+ZORG
yN
OvTuIsfVSsXw5C4Oi9CnqNo66xkMEwJFsKNs/0LalO3jGLlar/A6v2FpR+RTVwxw
FZU2she8xCnq/PKkjHHBn5W3zxTEH9bwGRIDItk7GoS7AnloM+yiZLADftyfq1Hl
k0gIGYxeS36QJ919puoHxybx2zfWY8GAVq+ePfPPkKr2OyQGXAdJ9jpQ44eIkoc6
q3irwkjl/hi20EV34PqE5BZGZx16FIA7DtdgXNcZYg3ExJOndqPNhdoAlwg0pkge
22OJ7aVwXUUPppX0OUxl59KGW20+SPJnKTizsocT15dqac8VQR5OMcIrWLVHnc
wH
qj27qA8QeIcapbeC+Jhw4yIpTGeKCPKq3hRFhWuaZq3rUuDjJZN5d+b8rXeoeLb/
q95i9JlocLpF6RwuFgzEios7sARfypAIcEfophti9NjtPT+8AL2ToCBMSfFL4ba7
EBg27R/MrCvWvQ3uyVnc/+jX93ckAwyzblc1BxoElPJ4WzLxlVtUZspiyrByq8MI
Qd2ne9627CNtjBYxej0J
=mZw5
-----END PGP SIGNATURE-----
---------------------------------------------------------------------
Т���������������������������������������������������������������������ХF�V�7V'67&�&R�R���âW6W'2�V�7V'67&�&TF��6B�6�R��&pФf�"FF�F����6����G2�R
Loading...