You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Jerry Malcolm <2n...@gmail.com> on 2012/04/04 23:31:25 UTC

request.login() not persistent

I am using TC 7.0 on a couple of servers.  I have id/pw fields and a
'login' button at the top of all guest pages on my site.  If the user
clicks the login, it goes to a guest page that does the request.login()
method call and then redirects to a protected page.  If the login fails,
the normal j_security login form stuff kicks in on the protected page and
the user logs in the old way.

OK, this worked on one server for several months.  It never worked on the
other server.  On that server, the request.login() succeeded according to
the logs.  But when it redirected to the protected page, the j_security
login form would appear.  I could log in from there and everything was
fine.

Then a couple of weeks ago, the server that was working just started doing
the same thing.  So now, the request.login() is useless.

I am looking at the logs.  The request.login() succeeded.  And the
request.getUserPrincipal() is the correct after the login on that page.
But as soon as I redirect to another page, the userPrincipal is now null.

I'm not saying I didn't have some configuration something wrong somewhere
on one of the servers and now it's wrong on both. But I'm totally baffled.
I have no clue what could be going wrong.  I'm not invalidating the session
or doing a request.logoff().  The sessionId is the same on the login page
and the subsequent redirect page.  And again, if I now login using the
j_security form on the redirected target page, I'm logged in for the
duration.  So it's nothing like an invalid id/pw or anything (and it fails
the same on all id/pws)

My first question... am I totally wrong on my philosophy for using the
request.login() method and redirecting to a protected page once logged in?
It did work for months.  So I assume that's not a fundamental design
problem.

If the design is ok, what's happening?  The log shows I'm logged in at the
end of one page that had the request.login() and then I'm not logged in at
the beginning of the redirect target page.

Any suggestions for what to try? How can I debug this?

Thx.

Re: request.login() not persistent

Posted by Konstantin Kolinko <kn...@gmail.com>.
2012/4/6 Jerry Malcolm <2n...@gmail.com>:
>
> Questions:
>
> 1) The <meta... html tag simply tells the browser when it reads the page to
> 'try again' at the new URL.  In my mind that is no different from the user
> responding to something on a page and submitting a request for a new page.
> Why is the session logged-on state information somehow lost in that
> interaction when it is maintained if the user just hits a button and goes
> to another page?
>
> 2) I assume the response.sendRedirect( ) with the encoded URL sends one of
> the 301 or 303 or something response codes back, right?  In either case,
> <meta... or 30x response code, why is the session info lost in one and not
> the other?
>
> 3) The biggest concern I have is that it worked for several months on one
> machine with the <meta... tag coding.  If it worked, then it stopped, now
> it works again, and I don't know why, my assumption is that it's going to
> stop working again for me sometime in the future.  What could I have done
> that made it work at one time on one machine and then stop?
>

1. When the client accesses the webapp second time it has to provide
session id to Tomcat.  The session id can be provided via Cookie:
header in the request or via sessionid "path parameter" in the URL.

If none of provided values matches existing session, Tomcat creates a new one.

Your "refresh" meta tag does not include sessionid, so when refresh
happens the information can come only from a cookie  and apparently
the value is absent or not correct.

Chris already answered how to modify your HTML page.

2. When a user is authenticated, recent Tomcat versions change the
sessionid value. All data are migrated to the new session id, so
nothing is lost, but the new id has to be sent to the client.

The id is sent via "Set-Cookie" response header.  If the client does
not receive the header it might be that
a. setHeader() failed, because some response data has already been
sent to the client and thus no more headers can be added before the
response text,
b. The headers have been cleared before sending the response.
c. The client browser does not respect the Set-Cookie header (the
cookies are disabled in the browser),
d. Tomcat is behind a proxy (e.g. HTTPD) and the path in the
set-cookie header does not match the address that client requested.
(Misconfigured reverse proxy)
e. Several Set-Cookie headers are received.


3. The client can have several different "sessionid" cookies. That is
because a cookie is scoped to a "path" on the server. Each webapp has
its own path.  The "path" value is sent in Set-Cookie response header,
 but it is usually not included in the "Cookie" response header.

Thus Tomcat usually sees several session cookies and have to find the
applicable one between them.

Clearing the cookies for your server in the browser sometimes can
change behaviour. (I cannot clearly say why it could help, because
those cookies should not be persistent, but in some situations some
people said that it helped).



You need to use some tool to see those response and request headers.
E.g. for Firefox you can use Firebug plugin's Network tab or Live Http
Headers plugin.

https://addons.mozilla.org/en-US/firefox/addon/firebug/
https://addons.mozilla.org/ru/firefox/addon/live-http-headers/

It is also possible to capture and inspect network traffic with some
sniffing tools like Wireshark or Fiddler.  It is also possible to
configure Tomcat to print specific headers into its access log.


Best regards,
Konstantin Kolinko

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


Re: request.login() not persistent

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Jerry,

On 4/5/12 6:11 PM, Jerry Malcolm wrote:
> Konstantin,
> 
> I was using:
> 
> <META HTTP-EQUIV="Refresh" CONTENT="0; URL=/userhome">
> 
> I changed it per your comment to:
> 
> <%  response.sendRedirect( response.encodeRedirectURL( "/userhome"
> )); %>

A more minimal change would have been this:

<META HTTP-EQUIV="Refresh" CONTENT="0; URL=<%=
response.encodeURL("/userhome") %>">

I always use request.getContextPath() + ... when building URLs, too:
that makes them relocatable. So the entire incantation would be:

<META HTTP-EQUIV="Refresh" CONTENT="0; URL=<%=
response.encodeURL(request.getContextPath() + "/userhome") %>" />

(I used <meta /> as an XHTML tag instead of <meta>, there. I dunno
what your content-type actually is, though).

You'll also want to make sure that your login <form> encodes any
session id information into the "action" attribute, in case a session
already exists. Otherwise, your webapp won't work unless cookies are
enabled.

> It's working now, but I have no clue what's going on.

Read the javadoc for HttpServletResponse.encodeURL and
HttpServletResponse.encodeRedirectURL.

> But I am apparently missing something major here, and I want to
> understand this.  So please educate me a bit...

Your client probably does not have the session id after you call
login(). The javadoc for login() doesn't say anything about
communicating a session id to the client, and I couldn't find in the
spec document itself any mention of cookies and the login() method
(though I didn't look terribly hard).

I suspect that login() does not automatically set a "Set-Cookie"
header on the response: you may have to do that yourself. You can tell
easily by rolling-back your changes and looking at the HTTP traffic
between your client and server during the login/login-again conversation.

> I completely understand the session philosophy and how the logon
> state is maintained in the session.  When it was failing the
> session id did not change between the logon page and the redirect
> target page.

As measured by what?

> So I'm assuming the session wasn't dropped.  It's like the logged
> on state was not saved in the session object.

According to the servlet spec, having a session and being logged-in
are equivalent, as long as authentication has occurred once for form
authentication.

> 1) The <meta... html tag simply tells the browser when it reads the
> page to 'try again' at the new URL.  In my mind that is no
> different from the user responding to something on a page and
> submitting a request for a new page. Why is the session logged-on
> state information somehow lost in that interaction when it is
> maintained if the user just hits a button and goes to another
> page?

Possibly because you are not properly encoding the session id in the
URL, coupled with loss or absence of the session cookie being sent in
the response.

> 2) I assume the response.sendRedirect( ) with the encoded URL sends
> one of the 301 or 303 or something response codes back, right?  In
> either case, <meta... or 30x response code, why is the session info
> lost in one and not the other?

See above.

> 3) The biggest concern I have is that it worked for several months
> on one machine with the <meta... tag coding.  If it worked, then it
> stopped, now it works again, and I don't know why, my assumption is
> that it's going to stop working again for me sometime in the
> future.  What could I have done that made it work at one time on
> one machine and then stop?

There could be several reasons, but the easiest thing that could have
happened, as Chuck suggests, is that cookies were disabled on the client.

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk9/DMsACgkQ9CaO5/Lv0PDQrgCgttz9YAJh0E/Irq0cupx/kO1o
ElAAn1mfiiQr90SU3pw9LMf95l41rzl+
=HMeM
-----END PGP SIGNATURE-----

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


RE: request.login() not persistent

Posted by "Caldarale, Charles R" <Ch...@unisys.com>.
> From: Jerry Malcolm [mailto:2ndgenfilms@gmail.com] 
> Subject: Re: request.login() not persistent

> I was using:
> <META HTTP-EQUIV="Refresh" CONTENT="0; URL=/userhome">

> I changed it per your comment to:
> <% response.sendRedirect( response.encodeRedirectURL( "/userhome" )); %>

> It's like the logged on state was not saved in the session object.

Or more likely that this particular client disabled cookies, thus requiring the sessionid to be included in the URL.  Using the encodeRedirectURL() method will do that, whereas the plain refresh will not.

 - Chuck


THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MATERIAL and is thus for use only by the intended recipient. If you received this in error, please contact the sender and delete the e-mail and its attachments from all computers.


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


Re: request.login() not persistent

Posted by Jerry Malcolm <2n...@gmail.com>.
Konstantin,

I was using:

<META HTTP-EQUIV="Refresh" CONTENT="0; URL=/userhome">

I changed it per your comment to:

<%  response.sendRedirect( response.encodeRedirectURL( "/userhome" )); %>

It's working now, but I have no clue what's going on.  I guess I should
just be happy and move on.  But I am apparently missing something major
here, and I want to understand this.  So please educate me a bit....  I
completely understand the session philosophy and how the logon state is
maintained in the session.  When it was failing the session id did not
change between the logon page and the redirect target page.  So I'm
assuming the session wasn't dropped.  It's like the logged on state was not
saved in the session object.

Questions:

1) The <meta... html tag simply tells the browser when it reads the page to
'try again' at the new URL.  In my mind that is no different from the user
responding to something on a page and submitting a request for a new page.
Why is the session logged-on state information somehow lost in that
interaction when it is maintained if the user just hits a button and goes
to another page?

2) I assume the response.sendRedirect( ) with the encoded URL sends one of
the 301 or 303 or something response codes back, right?  In either case,
<meta... or 30x response code, why is the session info lost in one and not
the other?

3) The biggest concern I have is that it worked for several months on one
machine with the <meta... tag coding.  If it worked, then it stopped, now
it works again, and I don't know why, my assumption is that it's going to
stop working again for me sometime in the future.  What could I have done
that made it work at one time on one machine and then stop?

Thanks for the education.

Jerry



On Thu, Apr 5, 2012 at 7:35 AM, Konstantin Kolinko
<kn...@gmail.com>wrote:

> 2012/4/5 Jerry Malcolm <2n...@gmail.com>:
> > I am using TC 7.0 on a couple of servers.  I have id/pw fields and a
> > 'login' button at the top of all guest pages on my site.  If the user
> > clicks the login, it goes to a guest page that does the request.login()
> > method call and then redirects to a protected page.  If the login fails,
> > the normal j_security login form stuff kicks in on the protected page and
> > the user logs in the old way.
> >
> > OK, this worked on one server for several months.  It never worked on the
> > other server.  On that server, the request.login() succeeded according to
> > the logs.  But when it redirected to the protected page, the j_security
> > login form would appear.  I could log in from there and everything was
> > fine.
> > (...)
>
> How do you perform your redirect?
> Do you call  HttpServletResponse.encodeRedirectURL( ) to encode
> sessionid in the redirection URL?
>
> Form authentication relies on sessions.  If new request does not
> belong to the same session (the correct session id is not send by
> client either in URL or with a cookie) then it does not have
> authentication.
>
>
> Best regards,
> Konstantin Kolinko
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>

Re: request.login() not persistent

Posted by Konstantin Kolinko <kn...@gmail.com>.
2012/4/5 Jerry Malcolm <2n...@gmail.com>:
> I am using TC 7.0 on a couple of servers.  I have id/pw fields and a
> 'login' button at the top of all guest pages on my site.  If the user
> clicks the login, it goes to a guest page that does the request.login()
> method call and then redirects to a protected page.  If the login fails,
> the normal j_security login form stuff kicks in on the protected page and
> the user logs in the old way.
>
> OK, this worked on one server for several months.  It never worked on the
> other server.  On that server, the request.login() succeeded according to
> the logs.  But when it redirected to the protected page, the j_security
> login form would appear.  I could log in from there and everything was
> fine.
> (...)

How do you perform your redirect?
Do you call  HttpServletResponse.encodeRedirectURL( ) to encode
sessionid in the redirection URL?

Form authentication relies on sessions.  If new request does not
belong to the same session (the correct session id is not send by
client either in URL or with a cookie) then it does not have
authentication.


Best regards,
Konstantin Kolinko

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


Re: request.login() not persistent

Posted by Konstantin Kolinko <kn...@gmail.com>.
2012/4/5 Jerry Malcolm <2n...@gmail.com>:
> Ok, finally located the zip in my downloads folder.  I'm currently running
> 7.0.23.  But I'm still curious about how to find out the version if I
> hadn't been able to locate the zip.  Is the version buried somewhere in the
> install folder?
>

catalina.jar
 ->  \org\apache\catalina\util\ServerInfo.properties


If you have *.bat files (e.g. from a zip distributive) you can run version.bat

Best regards,
Konstantin Kolinko

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


Re: request.login() not persistent

Posted by Jerry Malcolm <2n...@gmail.com>.
Ok, finally located the zip in my downloads folder.  I'm currently running
7.0.23.  But I'm still curious about how to find out the version if I
hadn't been able to locate the zip.  Is the version buried somewhere in the
install folder?

Jerry


On Wed, Apr 4, 2012 at 11:44 PM, Jerry Malcolm <2n...@gmail.com>wrote:

> Chris,
>
> Good question on the version.  But I'm not sure how to tell.  Both servers
> are in a directory named Tomcat 7.0.  But I can't remember if that was the
> default or if I forced that name.  Where can I look in the install
> directory to find the version?  I do know that I installed both servers
> around  the first of December 2011.  I haven't updated since then.
>
> You mentioned there were some known problems with using
> getUserPrincipal().  It might be related.  However, I was only using
> getUserPrincipal() for debug purposes to show whether I was logged on or
> not.  The real symptom of the problem was after logging on successfully and
> redirecting to another page, the login form page pops up forcing a second
> login.  If it's all tied together, then fine.  But if the problem you
> referenced only had to do with results of getUserPrincipal and nothing
> else, I doubt it is related to my problem.
>
> If there is a newer version since December, and there are known fixes in
> this area, I'll go ahead and upgrade.  But I really don't want to update
> and risk more instability unless there is reason to believe upgrading will
> fix the problem.
>
> Suggestions?
>
> Thx
>
>
> On Wed, Apr 4, 2012 at 7:49 PM, Christopher Schultz <
> chris@christopherschultz.net> wrote:
>
>> -----BEGIN PGP SIGNED MESSAGE-----
>> Hash: SHA1
>>
>> Jerry,
>>
>> On 4/4/12 5:31 PM, Jerry Malcolm wrote:
>> > I am using TC 7.0 on a couple of servers.
>>
>> 7.0.what?
>>
>> There have been a bunch of questions about authentication and
>> authorization lately involving a (somewhat) recent change when
>> resources aren't protected buy a <security-constraint> and are calling
>> request.getPrincipal().
>>
>> - -chris
>> -----BEGIN PGP SIGNATURE-----
>> Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
>> Comment: GPGTools - http://gpgtools.org
>> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
>>
>> iEYEARECAAYFAk987CwACgkQ9CaO5/Lv0PD9cgCgnzLbeVE97a+vPw0SWsafDpCT
>> e9sAoKYPJWqf86mkd7JtbBNDkrv2Wuwb
>> =K8KQ
>> -----END PGP SIGNATURE-----
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
>> For additional commands, e-mail: users-help@tomcat.apache.org
>>
>>
>

Re: request.login() not persistent

Posted by Jerry Malcolm <2n...@gmail.com>.
Chris,

Good question on the version.  But I'm not sure how to tell.  Both servers
are in a directory named Tomcat 7.0.  But I can't remember if that was the
default or if I forced that name.  Where can I look in the install
directory to find the version?  I do know that I installed both servers
around  the first of December 2011.  I haven't updated since then.

You mentioned there were some known problems with using
getUserPrincipal().  It might be related.  However, I was only using
getUserPrincipal() for debug purposes to show whether I was logged on or
not.  The real symptom of the problem was after logging on successfully and
redirecting to another page, the login form page pops up forcing a second
login.  If it's all tied together, then fine.  But if the problem you
referenced only had to do with results of getUserPrincipal and nothing
else, I doubt it is related to my problem.

If there is a newer version since December, and there are known fixes in
this area, I'll go ahead and upgrade.  But I really don't want to update
and risk more instability unless there is reason to believe upgrading will
fix the problem.

Suggestions?

Thx

On Wed, Apr 4, 2012 at 7:49 PM, Christopher Schultz <
chris@christopherschultz.net> wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Jerry,
>
> On 4/4/12 5:31 PM, Jerry Malcolm wrote:
> > I am using TC 7.0 on a couple of servers.
>
> 7.0.what?
>
> There have been a bunch of questions about authentication and
> authorization lately involving a (somewhat) recent change when
> resources aren't protected buy a <security-constraint> and are calling
> request.getPrincipal().
>
> - -chris
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
> Comment: GPGTools - http://gpgtools.org
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
>
> iEYEARECAAYFAk987CwACgkQ9CaO5/Lv0PD9cgCgnzLbeVE97a+vPw0SWsafDpCT
> e9sAoKYPJWqf86mkd7JtbBNDkrv2Wuwb
> =K8KQ
> -----END PGP SIGNATURE-----
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>

Re: request.login() not persistent

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Jerry,

On 4/4/12 5:31 PM, Jerry Malcolm wrote:
> I am using TC 7.0 on a couple of servers.

7.0.what?

There have been a bunch of questions about authentication and
authorization lately involving a (somewhat) recent change when
resources aren't protected buy a <security-constraint> and are calling
request.getPrincipal().

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk987CwACgkQ9CaO5/Lv0PD9cgCgnzLbeVE97a+vPw0SWsafDpCT
e9sAoKYPJWqf86mkd7JtbBNDkrv2Wuwb
=K8KQ
-----END PGP SIGNATURE-----

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