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

Reply via email to