Thomas,
On 11.01.2016 11:30, Thomas Scheffler wrote:
Am 08.01.16 um 17:02 schrieb Christopher Schultz:
Tomcat will change the session identifier when the user authenticates.
If you are creating a session before login, you'll see that the session
id changes when authentication is successful. This is to protect against
session-fixation attacks.
I re-login the user, if tomcat returns "null" on
HttpRequest.getUserPrincipal(). I noticed
that the sessionId changes. But if I am required to re-login the user on
parallel
requests, it depends on magic what sessionId is given after all responses are
delivered to
the browser.
You can see in the logs, that requested sessions are suddenly invalid.
I would not require an other call to the login method if servlet container
returns a user
once it is authenticated in a session.
Can you explain why the changing session id breaks your application? Are
you storing session ids somewhere and just not updating the session id
list when the session id changes? It should be possibly to listen for
that event and update your session id list. Or maybe there's a better
way to accomplish your goal rather than keeping your own session id
list. (I'm guessing you have a session id list because it would best
explain the behavior you are describing here.)
I do not save the http session id anywhere. The browser saves it in a cookie.
The cookie
is changing rapidly because the UserPrincipaö is not returned from the request.
Here is something I would prefer:
1. Every request that belongs to a given session returns a non null object when
calling
getUserPrincipal() after the login() method returns successfully.
2. As you have no control over the net and do not know in which order the
browser receives
its packets, you can not invalidate a sessionId in a snap. Tomcat has to
gracefully
invalidate it somehow.
An example:
1. Client logs in
2. Server responds with SID=SID1
3. Client request 2 resources in parallel
4. Server receives first request and handles it, returning SID=SID2
5. Server receives second request (with SID=SID2), which belongs to invalid
session. Code
is creating a new session than. Server response with SID=SID3
6. Client will use SID3 in future requests which belongs to the new session and
not the
original session where the user is logged in.
I think that the crux of the issue, is a proper understanding of how the HTTP protocol's
Basic Authentication works, in its basic form. Remember, HTTP is old, and at the
beginning, it did not envision "sessions", nor "simultaneous" requests. The basic idea was :
- client connects to, and sends one request to the server
- server processes request, and sends response to the client
- server closes connection, and forgets everything about the request just
processed
Then the next request from a client comes in, etc..
Everything else aftwerward, was built on the basic schema above, as "patches", to allow
for authentication, "sessions" composed of multiple requests/responses, "persistent
connections", "cookies" etc..
But the basic logic remains the same to this day.
For Basic authentication, the basic schema is as follows :
1) client establishes a connection to the server
2) client sends a request on that connection, for some server "resource"
3) the server checks if that resource is submitted to some form of
authentication/authorization/access control.
3.1) if not, the server returns the resource to the client, and the request/response cycle
is finished.
3.2) if yes (AAA required), the server checks if the request contains some form of
authentication/authorization.
3.2.1) if yes (auth provided), the server checks if this authentication/authorization
matches the requirements for this resource.
3.2.1.1) if yes, the server returns the resource, and the request/response is
finished.
3.2.1.2) if not, the server returns a "forbidden" response, and the request/response is
finished.
3.2.2) if not (no auth provided), the server returns a response "authorization required"
to the client, and the request/response is finished.
In a case like 3.2.2, the client must repeat the request, this time /with/ an
authentication as required by 3.2 above.
Whenever the server returns a response to the client, it can include a "set cookie" in
that response. The next time that the client sends a request to that same server, it will
then include this cookie, and maybe seeing this cookie will allow the server to respond
"yes" to the question at 3.2 above.
The above is the basic schema, as included in the HTTP protocol.
There are many other schemes that work, but you have to know that if you differ from the
schema above, then you are no longer within the strict HTTP protocol, and the
responsibility of making sure that your alternative scheme works in all circumstances, is
yours.
In particular, the above scheme will fail in the following scenario :
1) the client sends a request to the server, for a protected resource
2) the server responds with a "authorization required"
3) the client repeats the request, with a valid authentication
4) the server then prepares and sends the response, including a valid "authorization
token" (in this case, indirectly, this is the session-id cookie)
5) but, before this response has been totally processed by the client, the client already
starts sending another request for a protected resource.
Of course this request does not (yet) include the proper authentication token, because the
initial response (4) which contained it, has not yet been completely processed by the client.
So for the server, this (5) is a new and unauthenticated request, and the server treats it
as such : in your case, it creates a new session, and returns the response with this new
session. And this one is different from the session returned for the initial request.
(And because the cookie now returned for (5) has the same name as the cookie returned for
(4), it overwrites the previous cookie, and this previous cookie (and the session-id in
it) is now lost.
So the solution in your case, is to make sure, in your application logic, that the first
unauthenticated request would be totally processed by the server, and the response
processed by the client, before the client sends a second request.
If you do this, then the second client request /will/ contain the /same/ authentication
token as the first request, and you will not have this problem.
How to achieve this, is left as an exercise for the reader.
IMHO it would be also secure to lock the sessionId to the IP address instead of
changing
the id but less error-prone. You can even combine it and allow old sessionIds
only from
the original IP address.
If the servlet container would just use the session information for HTML pages
parallel
request are rare. But when serving cachable thumbnails it often like checking
headers and
return 304.
kind regards,
Thomas
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org