This project is used as a demo project for a javaee war based SPA application using secured endpoints and some HttpSession caching stuff.
Problematic has been exposed in a post to the undertow mailing list ; read more here.
When the app starts the following occures
- SPA application is accessed on a secured URL (index.html or time.html see below for differences)
- once loaded (
$(document).ready()
as demoed using jquery)- a first secured business endpoint
/init
is called. This endpoints initializes some data and put them in the HTTP session - once this call is successfully performed 20 other business endpoints
/data
are called (imagine some configuration loading or something else) and use the HTTP Session data to perform some logic
- a first secured business endpoint
Due to some race conditions on client side & to default JSESSIONID handling server side (session id change on login) several business calls to /data
can fail.
Here is an example of an execution of the SPA at http://localhost:8080/sessionid/index.html
The application logs/shows messages in which
[X::Y]
information correspond to:
- X the JSESSIONID received by the server, ie the one sent by the client (or null if none was received)
- Y the JSESSIONID used by the server
init at: /init [null::QAYLSwZSSu2pDQMaxnkTAkzciteWKKV-3YDDpzpD] application id generated: 3
0 -> /data [QAYLSwZSSu2pDQMaxnkTAkzciteWKKV-3YDDpzpD::Kr6hXPeKMXHIHpSJYSHdYxGvhtbjtTbi9yXRWLb7] data initialized for client{0} on app {3}
FAILURE: 3 :: /data no http session found for requested HTTP session id: QAYLSwZSSu2pDQMaxnkTAkzciteWKKV-3YDDpzpD
FAILURE: 1 :: /data no http session found for requested HTTP session id: QAYLSwZSSu2pDQMaxnkTAkzciteWKKV-3YDDpzpD
FAILURE: 6 :: /data no http session found for requested HTTP session id: QAYLSwZSSu2pDQMaxnkTAkzciteWKKV-3YDDpzpD
FAILURE: 2 :: /data no http session found for requested HTTP session id: QAYLSwZSSu2pDQMaxnkTAkzciteWKKV-3YDDpzpD
FAILURE: 4 :: /data no http session found for requested HTTP session id: QAYLSwZSSu2pDQMaxnkTAkzciteWKKV-3YDDpzpD
FAILURE: 8 :: /data no http session found for requested HTTP session id: QAYLSwZSSu2pDQMaxnkTAkzciteWKKV-3YDDpzpD
FAILURE: 5 :: /data no http session found for requested HTTP session id: QAYLSwZSSu2pDQMaxnkTAkzciteWKKV-3YDDpzpD
FAILURE: 7 :: /data no http session found for requested HTTP session id: QAYLSwZSSu2pDQMaxnkTAkzciteWKKV-3YDDpzpD
10 -> /data [Kr6hXPeKMXHIHpSJYSHdYxGvhtbjtTbi9yXRWLb7::Kr6hXPeKMXHIHpSJYSHdYxGvhtbjtTbi9yXRWLb7] data initialized for client{10} on app {3}
FAILURE: 9 :: /data no http session found for requested HTTP session id: QAYLSwZSSu2pDQMaxnkTAkzciteWKKV-3YDDpzpD
13 -> /data [Kr6hXPeKMXHIHpSJYSHdYxGvhtbjtTbi9yXRWLb7::Kr6hXPeKMXHIHpSJYSHdYxGvhtbjtTbi9yXRWLb7] data initialized for client{13} on app {3}
11 -> /data [Kr6hXPeKMXHIHpSJYSHdYxGvhtbjtTbi9yXRWLb7::Kr6hXPeKMXHIHpSJYSHdYxGvhtbjtTbi9yXRWLb7] data initialized for client{11} on app {3}
14 -> /data [Kr6hXPeKMXHIHpSJYSHdYxGvhtbjtTbi9yXRWLb7::Kr6hXPeKMXHIHpSJYSHdYxGvhtbjtTbi9yXRWLb7] data initialized for client{14} on app {3}
12 -> /data [Kr6hXPeKMXHIHpSJYSHdYxGvhtbjtTbi9yXRWLb7::Kr6hXPeKMXHIHpSJYSHdYxGvhtbjtTbi9yXRWLb7] data initialized for client{12} on app {3}
16 -> /data [Kr6hXPeKMXHIHpSJYSHdYxGvhtbjtTbi9yXRWLb7::Kr6hXPeKMXHIHpSJYSHdYxGvhtbjtTbi9yXRWLb7] data initialized for client{16} on app {3}
18 -> /data [Kr6hXPeKMXHIHpSJYSHdYxGvhtbjtTbi9yXRWLb7::Kr6hXPeKMXHIHpSJYSHdYxGvhtbjtTbi9yXRWLb7] data initialized for client{18} on app {3}
19 -> /data [Kr6hXPeKMXHIHpSJYSHdYxGvhtbjtTbi9yXRWLb7::Kr6hXPeKMXHIHpSJYSHdYxGvhtbjtTbi9yXRWLb7] data initialized for client{19} on app {3}
17 -> /data [Kr6hXPeKMXHIHpSJYSHdYxGvhtbjtTbi9yXRWLb7::Kr6hXPeKMXHIHpSJYSHdYxGvhtbjtTbi9yXRWLb7] data initialized for client{17} on app {3}
15 -> /data [Kr6hXPeKMXHIHpSJYSHdYxGvhtbjtTbi9yXRWLb7::Kr6hXPeKMXHIHpSJYSHdYxGvhtbjtTbi9yXRWLb7] data initialized for client{15} on app {3}
- standard SPA: no modifications the bug occures everytime
- stabilized JSESSIONID: introduction of unecessary sequential businees call before firing multiple asynchronuous data load calls
- prevent sessionId change SPA: usage of an undertow ServletExtension to prevent new JSESSIONID to be generated
How to reproduce:
- start wildly:
mvn clean wildfly:run
- deploy the app:
mvn wildfly:deploy
- open your browser, clean
localhost
cookies - navigate to http://localhost:8080/sessionid/index.html
- log into the app using:
user/u
- log into the app using:
- stop wildly:
mvn clean wildfly:shutdown
Notice all /data
calls fired asynchronously after the initial call to /init
.
How to reproduce:
- start wildly:
mvn clean wildfly:run
- deploy the app:
mvn wildfly:deploy
- open your browser, clean
localhost
cookies - navigate to http://localhost:8080/sessionid/time.html
- log into the app using:
user/u
- log into the app using:
- stop wildly:
mvn clean wildfly:shutdown
Notice the sequential call to /time
endpoint after the initial call to /init
and before all /data
asynchronous calls.
This /time
calls makes the regeneration of the JSESSIONID to occure before the /data
are fired and thus those calls are performed using a stable JSESSIONID.
In this scenario we use an undertow ServletExtension, DoNotChangeSessionIdOnLogin to disable the ChangeSessionIdOnLogin functionnality.
How to reproduce:
- start wildly:
mvn clean wildfly:run
- deploy the app with undertow extension:
mvn -Pundertow wildfly:deploy
- open your browser, clean
localhost
cookies - navigate to http://localhost:8080/sessionid-undertow/index.html
- log into the app using:
user/u
- log into the app using:
- stop wildly:
mvn clean wildfly:shutdown
Notice no rewrite of the JSESSIONID occures as the extension is active.