Tomcat 8.0.30 Session lost

2016-01-08 Thread Thomas Scheffler

Hi,

I have a very rare problem regarding session handling. It is 
reproducible only on a single server environment. Of cause this is the 
productive server.


I use container authentication and for simplicity 'tomcat-user.xml'.

Login is done via HttpServletRequest.login() method, whenever I need to 
access user and role information. The HttpServletRequest is saved in a 
ThreadLocal during request processing.


While that normally does the job. There is one servlet that produces 
simple thumbnails that triggers a problem. Session handling is done via 
Cookies.


A search result page lists several thumbnail images and the browser 
tries to load them (of cause) in parallel.


After the first thumbnail is loaded, the sessionId suddenly changes. As 
the browser now submitting the "false" sessionId, new sessions are 
created and the browser gets that new sessionId in the response. The 
session from the first request is lost at that point and so are the 
login credentials.


Why are sessionIds changing during the request?


Here are the logs I produce via a Servlet Filter:

- REQUEST -

[dev-mir]  DEBUG  MCRRequestDebugFilter: REQUEST URI: 
/mir/img/pdfthumb/Document_derivate_0049/2015-05-06_Protokoll%20der%20Sitzung%20des%20Fakult%C3%A4tsrates_%C3%B6ffentlich.pdf 


Cookies:
 {path=null, maxAge=-1, domain=null, name=JSESSIONID, comment=null, 
httpOnly=false, secure=false, class=class javax.servlet.http.Cookie, 
value=BD12BA0ED4546B5BC119727DAF97086B, version=0}

COOKIES END

REQUEST PARAMETERS:
 centerThumb: no,
REQUEST PARAMETERS END

Session is requested by cookie.
Session is not requested by URL.
Session is valid.
SESSION BD12BA0ED4546B5BC119727DAF97086B created at: 2016-01-07T15:18:51.068
SESSION ATTRIBUTES:
 mycore.session: {}
SESSION ATTRIBUTES END

Header:
accept: image/png,image/*;q=0.8,*/*;q=0.5
accept-encoding: gzip, deflate
accept-language: en-US,en;q=0.5
cache-control: max-age=0
connection: keep-alive
cookie: JSESSIONID=BD12BA0ED4546B5BC119727DAF97086B
host: cms.example.com:8291
if-modified-since: Wed, 06 Jan 2016 14:40:00 GMT
if-none-match: "4e0daa3453247bcfd985ee28de9616de"
referer: 
http://cms.example.com:8291/mir/servlets/solr/select?q=objectType:mods%20AND%20createdby:protokoll=mods.dateIssued%20desc
user-agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 
Firefox/38.0

HEADERS END

- RESPONSE  -

[dev-mir]  DEBUG  MCRRequestDebugFilter: RESPONSE URI: 
/mir/img/pdfthumb/Document_derivate_0049/2015-05-06_Protokoll%20der%20Sitzung%20des%20Fakult%C3%A4tsrates_%C3%B6ffentlich.pdf 


Status: 304
Header:
Cache-Control: max-age=31536000
ETag: "4e0daa3453247bcfd985ee28de9616de"
Expires: Sun, 24 Jan 2016 15:30:02 GMT
Set-Cookie: JSESSIONID=0A88AABC33D336900279B2378CD510B1; Path=/mir/; 
HttpOnly

HEADERS END


- NEXT REQUEST -

[dev-mir]  DEBUG  MCRRequestDebugFilter: REQUEST URI: 
/mir/img/pdfthumb/Document_derivate_0047/2015-03-25_Protokoll%20der%20Sitzung%20des%20Fakult%C3%A4tsrates_%C3%B6ffentlich.pdf 


Cookies:
 {path=null, maxAge=-1, domain=null, name=JSESSIONID, comment=null, 
httpOnly=false, secure=false, class=class javax.servlet.http.Cookie, 
value=BD12BA0ED4546B5BC119727DAF97086B, version=0}

COOKIES END

REQUEST PARAMETERS:
 centerThumb: no,
REQUEST PARAMETERS END

Session is requested by cookie.
Session is not requested by URL.
Session is not valid.
Header:
accept: image/png,image/*;q=0.8,*/*;q=0.5
accept-encoding: gzip, deflate
accept-language: en-US,en;q=0.5
cache-control: max-age=0
connection: keep-alive
cookie: JSESSIONID=BD12BA0ED4546B5BC119727DAF97086B
host: cms.example.com:8291
if-modified-since: Wed, 06 Jan 2016 14:40:02 GMT
if-none-match: "9e485dcd85a2b2ee373717a67c282873"
referer: 
http://cms.example.com:8291/mir/servlets/solr/select?q=objectType:mods%20AND%20createdby:protokoll=mods.dateIssued%20desc
user-agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 
Firefox/38.0

HEADERS END




[dev-mir]  DEBUG  MCRServlet: Setting ReqCharEncoding to: UTF-8
[dev-mir]  DEBUG  MCRHttpSessionListener: HttpSession 
20934FB3493889B9EE0FB425A002BB28 is beeing created by: 
org.apache.catalina.session.StandardSessionFacade@6a75756b


- RESPONSE -

[dev-mir]  DEBUG  MCRRequestDebugFilter: RESPONSE URI: 
/mir/img/pdfthumb/Document_derivate_0047/2015-03-25_Protokoll%20der%20Sitzung%20des%20Fakult%C3%A4tsrates_%C3%B6ffentlich.pdf 


Status: 304
Header:
Cache-Control: max-age=31536000
ETag: "9e485dcd85a2b2ee373717a67c282873"
Expires: Sun, 24 Jan 2016 15:30:03 GMT
Set-Cookie: JSESSIONID=20934FB3493889B9EE0FB425A002BB28; Path=/mir/; 
HttpOnly

HEADERS END

kind regards,

Thomas

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



Re: Tomcat 8.0.30 Session lost

2016-01-08 Thread Konstantin Kolinko
2016-01-08 19:02 GMT+03:00 Christopher Schultz :
> Thomas,
>
> On 1/8/16 8:00 AM, Thomas Scheffler wrote:
>> Am 08.01.16 um 11:43 schrieb Olaf Kock:
>>> Is there any chance that the first and correctly authenticated cookies
>>> (despite the debug output "secure=false") are https-only cookies and
>>> won't get transmitted in http, thus triggering new sessions? E.g. any
>>> chance they get rewritten at another level (Apache httpd, ServletFilter,
>>> others) to be secure only - or that the debug output is slightly
>>> incorrect because it omits the secure flag?
>>
>> This is from a test installation on the productive server where it can
>> only be observed. For simplicity I use the maven cargo plugin to setup
>> the tomcat here. It shows the same behavior on the productive server,
>> where it uses HTTPS in combination with Apache HTTPD.
>>
>> I use BeanUtil.describe() to produce the cookie String. So this should
>> all be correct.
>>
>> This error comes up on every browser with at least a certain number of
>> request to that servlet. It has something to do with a race condition or
>> side effect I'm not aware off.
>>
>> If I do not use container authentication, HTTP sessions won't get lost.
>>
>> Hunting this bugs for so many weeks now and ran out of ideas.
>
> 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.
>
> 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.)

FYI,
http://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpSessionIdListener.html

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



Re: Tomcat 8.0.30 Session lost

2016-01-08 Thread Olaf Kock
Is there any chance that the first and correctly authenticated cookies
(despite the debug output "secure=false") are https-only cookies and
won't get transmitted in http, thus triggering new sessions? E.g. any
chance they get rewritten at another level (Apache httpd, ServletFilter,
others) to be secure only - or that the debug output is slightly
incorrect because it omits the secure flag?

Olaf

Am 08.01.2016 um 10:07 schrieb Thomas Scheffler:
> Hi,
>
> I have a very rare problem regarding session handling. It is
> reproducible only on a single server environment. Of cause this is the
> productive server.
>
> I use container authentication and for simplicity 'tomcat-user.xml'.
>
> Login is done via HttpServletRequest.login() method, whenever I need
> to access user and role information. The HttpServletRequest is saved
> in a ThreadLocal during request processing.
>
> While that normally does the job. There is one servlet that produces
> simple thumbnails that triggers a problem. Session handling is done
> via Cookies.
>
> A search result page lists several thumbnail images and the browser
> tries to load them (of cause) in parallel.
>
> After the first thumbnail is loaded, the sessionId suddenly changes.
> As the browser now submitting the "false" sessionId, new sessions are
> created and the browser gets that new sessionId in the response. The
> session from the first request is lost at that point and so are the
> login credentials.
>
> Why are sessionIds changing during the request?
>
>
> Here are the logs I produce via a Servlet Filter:
>
> - REQUEST -
>
> [dev-mir]  DEBUG  MCRRequestDebugFilter: REQUEST URI:
> /mir/img/pdfthumb/Document_derivate_0049/2015-05-06_Protokoll%20der%20Sitzung%20des%20Fakult%C3%A4tsrates_%C3%B6ffentlich.pdf
>
> Cookies:
>  {path=null, maxAge=-1, domain=null, name=JSESSIONID, comment=null,
> httpOnly=false, secure=false, class=class javax.servlet.http.Cookie,
> value=BD12BA0ED4546B5BC119727DAF97086B, version=0}
> COOKIES END
>
> REQUEST PARAMETERS:
>  centerThumb: no,
> REQUEST PARAMETERS END
>
> Session is requested by cookie.
> Session is not requested by URL.
> Session is valid.
> SESSION BD12BA0ED4546B5BC119727DAF97086B created at:
> 2016-01-07T15:18:51.068
> SESSION ATTRIBUTES:
>  mycore.session: {}
> SESSION ATTRIBUTES END
>
> Header:
> accept: image/png,image/*;q=0.8,*/*;q=0.5
> accept-encoding: gzip, deflate
> accept-language: en-US,en;q=0.5
> cache-control: max-age=0
> connection: keep-alive
> cookie: JSESSIONID=BD12BA0ED4546B5BC119727DAF97086B
> host: cms.example.com:8291
> if-modified-since: Wed, 06 Jan 2016 14:40:00 GMT
> if-none-match: "4e0daa3453247bcfd985ee28de9616de"
> referer:
> http://cms.example.com:8291/mir/servlets/solr/select?q=objectType:mods%20AND%20createdby:protokoll=mods.dateIssued%20desc
> user-agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101
> Firefox/38.0
> HEADERS END
>
> - RESPONSE  -
>
> [dev-mir]  DEBUG  MCRRequestDebugFilter: RESPONSE URI:
> /mir/img/pdfthumb/Document_derivate_0049/2015-05-06_Protokoll%20der%20Sitzung%20des%20Fakult%C3%A4tsrates_%C3%B6ffentlich.pdf
>
> Status: 304
> Header:
> Cache-Control: max-age=31536000
> ETag: "4e0daa3453247bcfd985ee28de9616de"
> Expires: Sun, 24 Jan 2016 15:30:02 GMT
> Set-Cookie: JSESSIONID=0A88AABC33D336900279B2378CD510B1; Path=/mir/;
> HttpOnly
> HEADERS END
>
>
> - NEXT REQUEST -
>
> [dev-mir]  DEBUG  MCRRequestDebugFilter: REQUEST URI:
> /mir/img/pdfthumb/Document_derivate_0047/2015-03-25_Protokoll%20der%20Sitzung%20des%20Fakult%C3%A4tsrates_%C3%B6ffentlich.pdf
>
> Cookies:
>  {path=null, maxAge=-1, domain=null, name=JSESSIONID, comment=null,
> httpOnly=false, secure=false, class=class javax.servlet.http.Cookie,
> value=BD12BA0ED4546B5BC119727DAF97086B, version=0}
> COOKIES END
>
> REQUEST PARAMETERS:
>  centerThumb: no,
> REQUEST PARAMETERS END
>
> Session is requested by cookie.
> Session is not requested by URL.
> Session is not valid.
> Header:
> accept: image/png,image/*;q=0.8,*/*;q=0.5
> accept-encoding: gzip, deflate
> accept-language: en-US,en;q=0.5
> cache-control: max-age=0
> connection: keep-alive
> cookie: JSESSIONID=BD12BA0ED4546B5BC119727DAF97086B
> host: cms.example.com:8291
> if-modified-since: Wed, 06 Jan 2016 14:40:02 GMT
> if-none-match: "9e485dcd85a2b2ee373717a67c282873"
> referer:
> http://cms.example.com:8291/mir/servlets/solr/select?q=objectType:mods%20AND%20createdby:protokoll=mods.dateIssued%20desc
> user-agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101
> Firefox/38.0
> HEADERS END
>
>
>
>
> [dev-mir]  DEBUG  MCRServlet: Setting ReqCharEncoding to: UTF-8
> [dev-mir]  DEBUG  MCRHttpSessionListener: HttpSession
> 20934FB3493889B9EE0FB425A002BB28 is beeing created by:
> org.apache.catalina.session.StandardSessionFacade@6a75756b
>
> - RESPONSE -
>
> [dev-mir]  DEBUG  MCRRequestDebugFilter: RESPONSE URI:
> 

Re: Tomcat 8.0.30 Session lost

2016-01-08 Thread Thomas Scheffler

Am 08.01.16 um 11:43 schrieb Olaf Kock:

Is there any chance that the first and correctly authenticated cookies
(despite the debug output "secure=false") are https-only cookies and
won't get transmitted in http, thus triggering new sessions? E.g. any
chance they get rewritten at another level (Apache httpd, ServletFilter,
others) to be secure only - or that the debug output is slightly
incorrect because it omits the secure flag?


This is from a test installation on the productive server where it can 
only be observed. For simplicity I use the maven cargo plugin to setup 
the tomcat here. It shows the same behavior on the productive server, 
where it uses HTTPS in combination with Apache HTTPD.


I use BeanUtil.describe() to produce the cookie String. So this should 
all be correct.


This error comes up on every browser with at least a certain number of 
request to that servlet. It has something to do with a race condition or 
side effect I'm not aware off.


If I do not use container authentication, HTTP sessions won't get lost.

Hunting this bugs for so many weeks now and ran out of ideas.

regards,

Thomas

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



Re: Tomcat 8.0.30 Session lost

2016-01-08 Thread Thomas Scheffler

Am 08.01.16 um 14:03 schrieb André Warnier (tomcat):

Hi Thomas.

It is a bit difficult to figure out where the problem really is, without
having the full picture of what is going on (your web.xml configuration,
the order and precise timing in which requests really happen etc.).
But one thing I would really focus on, is the general overall logic of
the application, to see if the order in which things happen is really
consistent with the authentication method that you are using.
For example, if the initial call to the first page (the one which
contains the document links) does not immediately trigger a session
authentication, and in the meantime the browser starts making multiple
quasi-simultaneous requests for the links present in that page, then
things would get out of sync, since when the authentication does happen,
the session-id /will/ change (check Wikipedia for "web session
fixation"). That would overwrite the session-id cookie, perhaps in the
middle of the calls still being made to retrieve the document links
mentioned in the page.


Hi André,

I would like to give some insight information on how authentication is 
handled.


As the application can run in command line or as a web application we 
have a custom session handling (refer to it as 'core session'). Within 
the core session there is a UserInformation implementation attached. 
UserInformation can have different implementations and allows to ask for 
the user id and if the user in in a specific role.


In the HttpSession we only store the sessionId of our core session. When 
the http session is destroyed we also close the core session.


So there is only this one property "mycore.session" in the httpsession.

When using servlet container authentication (error happens only with 
it). I need to access the request object which is stored in a 
ThreadLocal and released at end of the request.


Here are the most important methods

private void loginIfNeeded() {
//getCurrentRequest() returns Optional
getCurrentRequest().ifPresent(currentRequest -> {
if (currentRequest.getUserPrincipal() == null) {
try {
currentRequest.login(user, pwd);
LOGGER.debug("Re-Logged in: " + user);
} catch (ServletException e) {
throw new RuntimeException(e);
}
}
});
}

public String getUserID() {
loginIfNeeded();
lastUser = getCurrentRequest()
.flatMap(r -> Optional.ofNullable(r.getUserPrincipal()))
.map(Principal::getName)
.orElseGet(() -> Optional.ofNullable(lastUser)
.orElseGet("guest");
return lastUser;
}

public boolean isUserInRole(String role) {
loginIfNeeded();
return getCurrentRequest().map(r -> 
r.isUserInRole(role)).orElse(Boolean.FALSE);

}

When the user first authenticated with his login credentials we put the 
servlet container user information to the core session. As the HTTP 
session is linked to it, we just need the http session to keep track of it.


The error happens to be later, (possibly) many requests after the login 
form that put UserInformation to the core session. So there is no racing 
condition at that position.


You can see in the code that I need to re-login from time to time, as 
the request object does not always return the remote user.


Why does that change the sessionId? How can I track the user than?

IMHO if HttpServletRequest.login() should only be called once in a http 
session than getUserPrincipal() should always return a user after 
login() is called on one request regarding to the same session, or?


But if calling login() always invalidates the old session we have a 
problem here.


As long as request are coming in sequentially this would be OK, as the 
browser gets a new cookie value with every response. But browsers are 
out of control and want to give cpu cores a good time.


Anyway. I hope you are not lost in the details and are still willing to 
help me.


regards,

Thomas

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



Re: Tomcat 8.0.30 Session lost

2016-01-08 Thread tomcat

On 08.01.2016 10:07, Thomas Scheffler wrote:

Hi,

I have a very rare problem regarding session handling. It is reproducible only 
on a single
server environment. Of cause this is the productive server.

I use container authentication and for simplicity 'tomcat-user.xml'.

Login is done via HttpServletRequest.login() method, whenever I need to access 
user and
role information. The HttpServletRequest is saved in a ThreadLocal during 
request processing.

While that normally does the job. There is one servlet that produces simple 
thumbnails
that triggers a problem. Session handling is done via Cookies.

A search result page lists several thumbnail images and the browser tries to 
load them (of
cause) in parallel.

After the first thumbnail is loaded, the sessionId suddenly changes. As the 
browser now
submitting the "false" sessionId, new sessions are created and the browser gets 
that new
sessionId in the response. The session from the first request is lost at that 
point and so
are the login credentials.

Why are sessionIds changing during the request?


Here are the logs I produce via a Servlet Filter:


[snip]

Hi Thomas.

It is a bit difficult to figure out where the problem really is, without having the full 
picture of what is going on (your web.xml configuration, the order and precise timing in 
which requests really happen etc.).
But one thing I would really focus on, is the general overall logic of the application, to 
see if the order in which things happen is really consistent with the authentication 
method that you are using.
For example, if the initial call to the first page (the one which contains the document 
links) does not immediately trigger a session authentication, and in the meantime the 
browser starts making multiple quasi-simultaneous requests for the links present in that 
page, then things would get out of sync, since when the authentication does happen, the 
session-id /will/ change (check Wikipedia for "web session fixation"). That would 
overwrite the session-id cookie, perhaps in the middle of the calls still being made to 
retrieve the document links mentioned in the page.





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



Re: Tomcat 8.0.30 Session lost

2016-01-08 Thread Christopher Schultz
Thomas,

On 1/8/16 8:00 AM, Thomas Scheffler wrote:
> Am 08.01.16 um 11:43 schrieb Olaf Kock:
>> Is there any chance that the first and correctly authenticated cookies
>> (despite the debug output "secure=false") are https-only cookies and
>> won't get transmitted in http, thus triggering new sessions? E.g. any
>> chance they get rewritten at another level (Apache httpd, ServletFilter,
>> others) to be secure only - or that the debug output is slightly
>> incorrect because it omits the secure flag?
> 
> This is from a test installation on the productive server where it can
> only be observed. For simplicity I use the maven cargo plugin to setup
> the tomcat here. It shows the same behavior on the productive server,
> where it uses HTTPS in combination with Apache HTTPD.
> 
> I use BeanUtil.describe() to produce the cookie String. So this should
> all be correct.
> 
> This error comes up on every browser with at least a certain number of
> request to that servlet. It has something to do with a race condition or
> side effect I'm not aware off.
> 
> If I do not use container authentication, HTTP sessions won't get lost.
> 
> Hunting this bugs for so many weeks now and ran out of ideas.

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.

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.)

-chris

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