Bug 54340

Summary: Form-based authentication + url rewriting does not work
Product: Tomcat 7 Reporter: Koen Deforche <koen>
Component: CatalinaAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED DUPLICATE    
Severity: major    
Priority: P2    
Version: unspecified   
Target Milestone: ---   
Hardware: PC   
OS: Linux   
Attachments: Test case that reproduces the bug

Description Koen Deforche 2012-12-21 16:23:25 UTC
Created attachment 29788 [details]
Test case that reproduces the bug

Form-based authentication in combination with URL rewriting does not work: when the user successfully authenticates he is redirected to the application but, the login page is shown again. When he reloads this page then he does get to the actual application !

The correct behaviour (which can be observed in for example jetty) is that the user correctly can access the actual application after logging in.

The following access log illustrates the odd behaviour:

127.0.0.1 - - [21/Dec/2012:17:10:30 +0100] "GET /test-form-auth/protected HTTP/1.1" 200 450
127.0.0.1 - - [21/Dec/2012:17:10:35 +0100] "POST /test-form-auth/j_security_check;jsessionid=DBE966BD9F3CA8A7F57B5677F1D831F4 HTTP/1.1" 302 -
127.0.0.1 - - [21/Dec/2012:17:10:35 +0100] "GET /test-form-auth/protected;jsessionid=DBE966BD9F3CA8A7F57B5677F1D831F4 HTTP/1.1" 200 450
127.0.0.1 - koen [21/Dec/2012:17:10:38 +0100] "GET /test-form-auth/protected;jsessionid=DBE966BD9F3CA8A7F57B5677F1D831F4 HTTP/1.1" 200 59

Notice the two last requests: they are identical, yet, the server returns the first time the login.jsp page, and the second time the actual web application.

On top of this (and perhaps related to these problems), in the actual web application a different session ID is actually printed.

The same application in jetty regenerates the session ID (after authentication) and directly redirects to this new session, reporting the same session ID within the application as is visible in the URL.

The project in attachment is a self-contained test case that reproduces the problem, including an ant script to create the war file.
Comment 1 Konstantin Kolinko 2012-12-21 18:08:10 UTC
1. Tomcat version = ?

I'd guess that you are facing bug 53584, which was fixed in 7.0.30.


> On top of this (and perhaps related to these problems), in the actual web
> application a different session ID is actually printed.

2. As expected. See "changeSessionIdOnAuthentication" in
http://tomcat.apache.org/tomcat-7.0-doc/config/valve.html

3. It works for me in 7.0.34

To be sure, I changed the <web-app> element in your web.xml to use version="3.0" and relevant version of the schema, instead of 2.3 that you are using.

A fragment of my access log:

127.0.0.1 - - [21/Dec/2012:20:38:59 +0400] "GET /test-form-auth/protected HTTP/1.1" 200 450
127.0.0.1 - - [21/Dec/2012:20:39:15 +0400] "POST /test-form-auth/j_security_check;jsessionid=38B9A84964A6005AA58ABC5CDA9F6367 HTTP/1.1" 302 -
127.0.0.1 - tomcat [21/Dec/2012:20:39:15 +0400] "GET /test-form-auth/protected HTTP/1.1" 200 59

Tested both with Firefox 17.0.1 and IE 8. Tomcat 7.0.34, BIO connector.


Though there are two bits of a mystery:
------------------
a) Why access log did print jsessionid in the second request, but did not in the third one? FireBug shows that there was jsessionid in the request that Firefox sent.

b) The page that is shown after the test. I tried to refresh it. It worked, but it ended up with 2 jsessionid parameters in the URL (as displayed in the address bar).



Steps to reproduce for b):

1. Go to
http://localhost:8080/test-form-auth/protected;jsessionid=84C65A4F88EFC446C0DADAC649BD53BE

2. Login form is displayed (as expected). Log in.

3. After logging in the test page is displayed (as expected),
but somehow the address bar shows 2 jsessionid path parameters in the URL:

http://localhost:8080/test-form-auth/protected;jsessionid=C578A9AAB9E8020B438270DD65DC174C;jsessionid=9DB72687A728F05162C1C3D1B7E94F90

Reproducible both with Firefox 17 and IE 8. Firebug shows that Location header in the 302 response for the POST request to j_security_check had 2 jsessionid:

Location: http://localhost:8080/test-form-auth/protected;jsessionid=C578A9AAB9E8020B438270DD65DC174C;jsessionid=9DB72687A728F05162C1C3D1B7E94F90

Access log:
127.0.0.1 - - [21/Dec/2012:21:06:31 +0400] "GET /test-form-auth/protected;jsessionid=C578A9AAB9E8020B438270DD65DC174C HTTP/1.1" 200 450
127.0.0.1 - - [21/Dec/2012:21:06:47 +0400] "POST /test-form-auth/j_security_check;jsessionid=9DB72687A728F05162C1C3D1B7E94F90 HTTP/1.1" 302 -
127.0.0.1 - tomcat [21/Dec/2012:21:06:47 +0400] "GET /test-form-auth/protected;jsessionid=C578A9AAB9E8020B438270DD65DC174C HTTP/1.1" 200 59
Comment 2 Koen Deforche 2012-12-26 09:43:26 UTC
Hey,

Indeed, it looks like the same bug. I really did search the database, but, apparently, not good enough, so sorry for that. We will test with a more recent version (we tested with tomcat 7.0.26 and 7.0.28).

>> On top of this (and perhaps related to these problems), in the actual web
>> application a different session ID is actually printed.
>
>2. As expected. See "changeSessionIdOnAuthentication" in
>http://tomcat.apache.org/tomcat-7.0-doc/config/valve.html

I do understand that the session ID is changed, however, I would have assumed that authentication happens when the credential are received, i.e. in the POST to j_security_check; and then a redirect happens to a URL with a new session ID. But this is not what is observed, instead it seems that either only the session ID is changed when the request arrives to the actual application, or, there is a mismatch between the session ID in the URL and the one that is reported by sessionID() ?

The expected behavior (to me), which is seen in jetty, is that the first access to the actual application (after authentication) has a sessionId() reported that is equal to the session ID in the URL, but is possibly changed from a sessionId() that was used prior to authentication.

Regards,
koen
Comment 3 Mark Thomas 2013-01-04 22:16:29 UTC

*** This bug has been marked as a duplicate of bug 53584 ***