You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Russ Kepler <ru...@kepler-eng.com> on 2012/11/08 16:48:48 UTC

Form based login authentication

Using:

Linux main 3.2.0-32
Tomcat 7.0.32
Java version "1.7.0_09"
(working through Eclipse Juno)

I've been assigned what should have been a pretty simple task, a jnlp launcher 
following a login to the web server.  I've implemented what seemed to me to be 
the simplest solution - form based login going through j_security_check, after 
which I pass the jsessionid through a .jnlp built on the fly.  This would pass 
the session to the Java Web Start and let me pass it as well to me 
application.  I was planning on having the application perform the login 
manually if it isn't given a working session on startup.  I'm not having a lot 
of luck.

I believe that I have the user login bit setup correct as I see the failed 
login when I enter the incorrect login.  When I enter a working name/password 
pair I get a 408 - timeout.  That goes away if I change web.xml:

    <session-config>
        <session-timeout>30</session-timeout>
        <tracking-mode>URL</tracking-mode>
    </session-config>

to the cookie form:

    <session-config>
        <session-timeout>30</session-timeout>
        <tracking-mode>COOKIE</tracking-mode>
    </session-config>

After that everything works as expected, so it appears that the 408 is related 
to the URL tracking.  I've tried this with the internal browser in Eclipse as 
well as Firefox and get the same problem.  I'm guessing the j_security_check 
isn't redirecting with a rewritten URL and instead returns a timeout on a 
successful login.

If this is a known behaviour I have not been able to find anything after 
spending a lot of time in google (more people seem to be trying to get rid of 
the url rewrite), but since this is a new environment I may not have a grip of 
the appropriate tags to be searching.


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


Re: Form based login authentication

Posted by Russ Kepler <ru...@kepler-eng.com>.
On Monday, November 19, 2012 12:33:26 PM Brian Burch wrote:

> This issue was discussed at length on the users mailing list under this
> topic: "AuthenticatorBase setChangeSessionIdOnAuthentication without
> cookies"
> http://mail-archives.apache.org/mod_mbox/tomcat-users/201209.mbox/%3C505EDA8
> 7.1080404@pingtoo.com%3E
> 
> 
> Authenticated access to restricted resources can only happen if the
> browser tells tomcat the session id when it requests ANY of those
> restricted resources. This is usually done via cookies, but when cookies
> are turned off the webapp has to keep reminding the browser of the
> session id - especially if the default behaviour is being used by the
> Container, when the session id is deliberately changed after authentication.
> 
> Your protected jsp's MUST ALL use response.encodeURL() if you want your
> webapp to work properly without cookies.

OK, my confusion came from accessing the root and expecting the web.xml 
<welcome-file> tag to take care of my base page.  Is there a reason it doesn't 
get an encodeURL()?  When I make my initial page something that exists *and* 
encode the j_security_check things work, at least I get to my next stopping 
point with a .jnlp (I'd like javaws to load securely *then* access the 
servlets securely.  JWS documentation seems lacking and a couple of posts over 
here:

http://forums.oracle.com/forums/forum.jspa?forumID=944&start=0

haven't elicited any enlightening responses.
 
> When using an IDE you need to be careful of classloader issues. Tomcat's
> classloader environment is sophisticated and I sometimes encounter
> strange behaviour under netbeans because it tries to cache classes for
> speed, but this sometimes means my changes do not seem to have worked.
> This can always be proved by restarting netbeans.

That's why I mentioned it.  When I get confused at a response I stop the web 
server from inside Eclipse, when that fails to unconfuse me I exit Eclipse and 
start back up.   So far I haven't seen much effect, i.e. my confusion remains, 
but at least I can break for coffee.

> I don't use eclipse, so I can't comment on your specific problems.
> However, you can simplify your debugging by running tomcat standalone
> and attaching your debugger to it.

I may get to that point, probably when I'm testing the .war

Thanks for looking at this.

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


Re: Form based login authentication

Posted by Brian Burch <br...@pingtoo.com>.
On 10/11/12 17:47, Russ Kepler wrote:
> On Saturday, November 10, 2012 05:14:43 PM you wrote:
>
>> I thought it would helpful to let you know that I am very nearly ready
>> to submitting a lot of new unit tests for the FormAuthenticator class.
>> The new tests explore url path extensions to carry the sessionid in the
>> absence of cookies.
>>
>> I have a couple of cases left to develop, which are closely related to
>> your situation. If you are not in too much hurry, then I suggest you
>> wait for me, rather than waste time developing a demonstration war...
>>
>> I'll get back to you later this week if I need any more information
>> about your problem, or even if I think you are just experiencing a
>> "that's just the way it works" situation (at the moment I am not sure).
>
> Brian,
>
> Thanks for the post, good to hear that my post hasn't been lost.  I do have a
> cheap test in a .war, attached.  All it does is to try and get through the
> form login.  Form login works with cookie sessions but fails with URL
> sessions.  I've left commented out all the attempts to get past this in
> login.jsp and in other files.
>
> I really think the form login with URL validation got broken recently.  I've
> not been able to make it work with 7.0.32 but think it was working with an
> earlier revision.  I suspect that the combination of invalidating the original
> session and creating a new one combined with losing the original requested URL
> forces folks to simply cycle through j_security_check - if login fails it goes
> to the error handler, if I pass it fails with a 408 because it's lost the
> original URL.  The same logic works when I change the tracking-mode from URL
> to COOKIE; leading me to believe that I have things setup and it's some
> breakage in authentication.
>
> server.xml:
>
>        <Realm className="org.apache.catalina.realm.LockOutRealm">
>          <!-- This Realm uses the UserDatabase configured in the global JNDI
>               resources under the key "UserDatabase".  Any edits
>               that are performed against this UserDatabase are immediately
>               available for use by the Realm.  -->
>          <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
> resourceName="UserDatabase"/>
>        </Realm>
>
> web.xml
>
> <session-config>
>          <session-timeout>30</session-timeout>
>          <tracking-mode>URL</tracking-mode>
>          <!--  tracking-mode>COOKIE</tracking-mode -->
> </session-config>
>
> tomcat-users.xml:
>
> <tomcat-users>
> 	<role rolename="webtyper"/>
> 	<user username="webtyper" password="webtyper" roles="webtyper"/>
> </tomcat-users>

Russ,

Sorry about the delay.

I started to look at your demo war. Tomcat builds with a standard user 
and role, so I decided to open your war and edit your web.xml to use 
tomcat/tomcat.

I noticed that you have only one security constraint:

     <security-constraint>
         <web-resource-collection>
             <web-resource-name>Typer</web-resource-name>
             <url-pattern>/*</url-pattern>
             <http-method>GET</http-method>
             <http-method>POST</http-method>
         </web-resource-collection>
         <auth-constraint>
             <role-name>tomcat</role-name>
         </auth-constraint>
     </security-constraint>

That didn't look right to me, because you also have:

     <login-config>
         <auth-method>FORM</auth-method>
         <form-login-config>
             <form-login-page>/logon.jsp</form-login-page>
             <form-error-page>/logonError.jsp</form-error-page>
         </form-login-config>
     </login-config>

I /thought/ that meant an unauthenticated user does not have permission 
to access your logon.jsp or logonError.jsp files. I have always included 
an explicit "allow unauthenticated users" security constraint for those 
pages in my own web.xml files.

HOWEVER, I WAS WRONG! When I followed your webapp through the 
FormAuthenticator I discovered the forwardToLoginPage and 
forwardToErrorPage methods do not make any reference to the security 
constraints for the webapp. i.e. the form-login-config pages are 
automatically accessible to unauthenticated users. (Thanks for giving me 
the opportunity to learn something new!)


Once I had your with-cookies demo working properly, I then added the 
session-config section with a tracking-mode of URL to your web.xml. I 
was lazy and didn't use a stable tomcat release - I just ran it under my 
current version of the trunk, which is deliberately a couple of weeks 
back-level. I was very surprised to find that pressing the submit button 
with a good username and password threw the browser out with a 
connection reset!

I little bit of debugging and I discovered that authentication was 
looping - each time j_security_check authenticated ok, but the session 
created by the original HTTP GET to your protected resource was not 
being recovered from the cache.

The line in your logon.jsp:

<form action="j_security_check" method=post >

... was the cause of the loop. I replaced it with:

<form method="POST" action='<%= response.encodeURL("j_security_check") %>' >

... and the logon was successful. This is because the browser will now 
POST the FORM with a url path parameter which encodes the correct 
jsessionid value.


This issue was discussed at length on the users mailing list under this 
topic: "AuthenticatorBase setChangeSessionIdOnAuthentication without 
cookies"
http://mail-archives.apache.org/mod_mbox/tomcat-users/201209.mbox/%3C505EDA87.1080404@pingtoo.com%3E


Authenticated access to restricted resources can only happen if the 
browser tells tomcat the session id when it requests ANY of those 
restricted resources. This is usually done via cookies, but when cookies 
are turned off the webapp has to keep reminding the browser of the 
session id - especially if the default behaviour is being used by the 
Container, when the session id is deliberately changed after authentication.

Your protected jsp's MUST ALL use response.encodeURL() if you want your 
webapp to work properly without cookies.


Note to self: is my observed j_security_check loop an artefact of my 
improperly updated sandbox, or is there a bug? I will try to add a 
specific unit test to explore this behaviour soon.

> As you can tell I'm not a regular user of Tomcat.  That plus the issues in
> Eclipse (I've got 3 versions of Juno and they all f'up web stuff in different
> ways) I'm not completely sure of just where my problems are - Tomcat
> (&friends) Eclipse or me.  All I really want to do is to validate users on the
> web & launch the Java Web Start (working without authentication) or validate
> when the java code is directly executed.  I didn't expect to spend weeks on
> this (actually hours of frustration followed by days of ennui).
>
> -- Russ

When using an IDE you need to be careful of classloader issues. Tomcat's 
classloader environment is sophisticated and I sometimes encounter 
strange behaviour under netbeans because it tries to cache classes for 
speed, but this sometimes means my changes do not seem to have worked. 
This can always be proved by restarting netbeans.

I don't use eclipse, so I can't comment on your specific problems. 
However, you can simplify your debugging by running tomcat standalone 
and attaching your debugger to it.

Regards,

Brian

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


Re: Form based login authentication

Posted by Brian Burch <br...@pingtoo.com>.
On 10/11/12 17:47, Russ Kepler wrote:
> On Saturday, November 10, 2012 05:14:43 PM you wrote:
>
>> I thought it would helpful to let you know that I am very nearly ready
>> to submitting a lot of new unit tests for the FormAuthenticator class.
>> The new tests explore url path extensions to carry the sessionid in the
>> absence of cookies.
>>
>> I have a couple of cases left to develop, which are closely related to
>> your situation. If you are not in too much hurry, then I suggest you
>> wait for me, rather than waste time developing a demonstration war...
>>
>> I'll get back to you later this week if I need any more information
>> about your problem, or even if I think you are just experiencing a
>> "that's just the way it works" situation (at the moment I am not sure).
>
> Brian,
>
> Thanks for the post, good to hear that my post hasn't been lost.  I do have a
> cheap test in a .war, attached.  All it does is to try and get through the
> form login.  Form login works with cookie sessions but fails with URL
> sessions.  I've left commented out all the attempts to get past this in
> login.jsp and in other files.
>
> I really think the form login with URL validation got broken recently.  I've
> not been able to make it work with 7.0.32 but think it was working with an
> earlier revision.  I suspect that the combination of invalidating the original
> session and creating a new one combined with losing the original requested URL
> forces folks to simply cycle through j_security_check - if login fails it goes
> to the error handler, if I pass it fails with a 408 because it's lost the
> original URL.  The same logic works when I change the tracking-mode from URL
> to COOKIE; leading me to believe that I have things setup and it's some
> breakage in authentication.

Thanks. I appreciate you providing more details before I got round to 
asking!

FormAuthenticator and its super class, Authenticator, continue to 
surprise me with wrinkles every time I step through them with a debugger.

I'm not going to speculate further about your problem at this stage, 
because that could simply lay down trails of red herrings. However, my 
own interest is in a similar-sounding, rare and as-yet-unreproducible 
problem that a) uses cookies, and b) operates within a single-signon 
environment. Until I'm satisfied with the completeness of the jUnit test 
suite /without/ SSO, I'm not going near my own problem!

I hope you don't have a production issue, because it really will take me 
all of this week to put in enough time to get round to looking at your war.

I'm a contributor, not a submitter, so there is quite a long delay 
between me preparing a patch and having it committed. I develop my 
changes against the trunk, which means they will apply to the next tc7 
release (and also tc6 provided they are easy to implement).

Brian

p.s. you should reply to the tomcat users list, not direct to me, so 
that the thread remains a complete narrative to anyone following it in 
future.

> server.xml:
>
>        <Realm className="org.apache.catalina.realm.LockOutRealm">
>          <!-- This Realm uses the UserDatabase configured in the global JNDI
>               resources under the key "UserDatabase".  Any edits
>               that are performed against this UserDatabase are immediately
>               available for use by the Realm.  -->
>          <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
> resourceName="UserDatabase"/>
>        </Realm>
>
> web.xml
>
> <session-config>
>          <session-timeout>30</session-timeout>
>          <tracking-mode>URL</tracking-mode>
>          <!--  tracking-mode>COOKIE</tracking-mode -->
> </session-config>
>
> tomcat-users.xml:
>
> <tomcat-users>
> 	<role rolename="webtyper"/>
> 	<user username="webtyper" password="webtyper" roles="webtyper"/>
> </tomcat-users>
>
> As you can tell I'm not a regular user of Tomcat.  That plus the issues in
> Eclipse (I've got 3 versions of Juno and they all f'up web stuff in different
> ways) I'm not completely sure of just where my problems are - Tomcat
> (&friends) Eclipse or me.  All I really want to do is to validate users on the
> web & launch the Java Web Start (working without authentication) or validate
> when the java code is directly executed.  I didn't expect to spend weeks on
> this (actually hours of frustration followed by days of ennui).
>
> -- Russ
>


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


Re: Form based login authentication

Posted by Brian Burch <br...@pingtoo.com>.
On 08/11/12 22:48, Russ Kepler wrote:
> On Friday, November 09, 2012 01:02:55 AM Konstantin Kolinko wrote:
>
>> 1. When and how do you obtain the value for your jsessionid? Beware
>> that the session id is changing when you do authentication. That is
>> done to prevent session fixation attacks.
>
> The .jnlp would be generated on the fly after a login, so it would have the
> jsessionid just generated by the user authentication - if I can get through
> the login.  But I'm not getting there as a successful login isn't redirected
> to the original target (or, perhaps, the jsessionid generated by the login
> isn't properly appended to the original url).
>
>> 2. It isn't timeout.
>> It means that you've got a new session, and so Tomcat does not know
>> where to redirect you after the login.
>>
>> See
>> response.sendError(HttpServletResponse.SC_REQUEST_TIMEOUT
>> call in o.a.c.authenticator.FormAuthenticator
>
> I landed in the login as a function of the authentication, so it seems that I
> should end up where I was originally trying to go after the authentication
> succeeds.  Since the session has to be in the URL there should have been a URL
> rewrite for the new session performed after the login and session was created.
>
> This old thread seem applicable:
>
> http://tomcat.10.n6.nabble.com/AuthenticatorBase-
> setChangeSessionIdOnAuthentication-without-cookies-td4987045.html
>
> It's entirely possible (likely) that I'm missing something, but it sure looks
> like you can't get through a login.jsp with URL based session data.  I'd be
> delighted to wrap this test case up in a .war, I was posting here to make sure
> that I wasn't completely missing some point.

Russ,

I thought it would helpful to let you know that I am very nearly ready 
to submitting a lot of new unit tests for the FormAuthenticator class. 
The new tests explore url path extensions to carry the sessionid in the 
absence of cookies.

I have a couple of cases left to develop, which are closely related to 
your situation. If you are not in too much hurry, then I suggest you 
wait for me, rather than waste time developing a demonstration war...

I'll get back to you later this week if I need any more information 
about your problem, or even if I think you are just experiencing a 
"that's just the way it works" situation (at the moment I am not sure).

Regards,

Brian


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


Re: Form based login authentication

Posted by Russ Kepler <ru...@kepler-eng.com>.
On Friday, November 09, 2012 01:02:55 AM Konstantin Kolinko wrote:

> 1. When and how do you obtain the value for your jsessionid? Beware
> that the session id is changing when you do authentication. That is
> done to prevent session fixation attacks.

The .jnlp would be generated on the fly after a login, so it would have the 
jsessionid just generated by the user authentication - if I can get through 
the login.  But I'm not getting there as a successful login isn't redirected 
to the original target (or, perhaps, the jsessionid generated by the login 
isn't properly appended to the original url).

> 2. It isn't timeout.
> It means that you've got a new session, and so Tomcat does not know
> where to redirect you after the login.
> 
> See
> response.sendError(HttpServletResponse.SC_REQUEST_TIMEOUT
> call in o.a.c.authenticator.FormAuthenticator

I landed in the login as a function of the authentication, so it seems that I 
should end up where I was originally trying to go after the authentication 
succeeds.  Since the session has to be in the URL there should have been a URL 
rewrite for the new session performed after the login and session was created.  

This old thread seem applicable:

http://tomcat.10.n6.nabble.com/AuthenticatorBase-
setChangeSessionIdOnAuthentication-without-cookies-td4987045.html

It's entirely possible (likely) that I'm missing something, but it sure looks 
like you can't get through a login.jsp with URL based session data.  I'd be 
delighted to wrap this test case up in a .war, I was posting here to make sure 
that I wasn't completely missing some point.


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


Re: Form based login authentication

Posted by Konstantin Kolinko <kn...@gmail.com>.
2012/11/8 Russ Kepler <ru...@kepler-eng.com>:
> Using:
>
> Linux main 3.2.0-32
> Tomcat 7.0.32
> Java version "1.7.0_09"
> (working through Eclipse Juno)
>
> I've been assigned what should have been a pretty simple task, a jnlp launcher
> following a login to the web server.  I've implemented what seemed to me to be
> the simplest solution - form based login going through j_security_check, after
> which I pass the jsessionid through a .jnlp built on the fly.  This would pass

1. When and how do you obtain the value for your jsessionid? Beware
that the session id is changing when you do authentication. That is
done to prevent session fixation attacks.

> the session to the Java Web Start and let me pass it as well to me
> application.  I was planning on having the application perform the login
> manually if it isn't given a working session on startup.  I'm not having a lot
> of luck.
>
> I believe that I have the user login bit setup correct as I see the failed
> login when I enter the incorrect login.  When I enter a working name/password
> pair I get a 408 - timeout.  That goes away if I change web.xml:
>
>     <session-config>
>         <session-timeout>30</session-timeout>
>         <tracking-mode>URL</tracking-mode>
>     </session-config>
>
> to the cookie form:
>
>     <session-config>
>         <session-timeout>30</session-timeout>
>         <tracking-mode>COOKIE</tracking-mode>
>     </session-config>
>
> After that everything works as expected, so it appears that the 408 is related
> to the URL tracking.  I've tried this with the internal browser in Eclipse as
> well as Firefox and get the same problem.  I'm guessing the j_security_check
> isn't redirecting with a rewritten URL and instead returns a timeout on a
> successful login.
>

2. It isn't timeout.
It means that you've got a new session, and so Tomcat does not know
where to redirect you after the login.

See
response.sendError(HttpServletResponse.SC_REQUEST_TIMEOUT
call in o.a.c.authenticator.FormAuthenticator


> If this is a known behaviour I have not been able to find anything after
> spending a lot of time in google (more people seem to be trying to get rid of
> the url rewrite), but since this is a new environment I may not have a grip of
> the appropriate tags to be searching.
>

BTW, if you want to try running with a debugger, see
https://wiki.apache.org/tomcat/FAQ/Developing#Debugging

Best regards,
Konstantin Kolinko

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