You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by "Algirdas P. Veitas" <av...@mail.allesta.com> on 2002/11/12 05:56:46 UTC

Servlet Spec interpretation FORM-based authentication

Folks,

I am running into an issue with FORM-based authentication
using 4.1.12 (and 4.0.4).  It seems as if the implementation
is not in line with the 2.3 Servlet Specification.  Specifically,
the Servlet Spec states:

SRV.12.5.3 Form Base Authentication
--snip--
J2EE.12.5.3.1 Login Form Notes
--snip--
"If the form based login is invoked because of an HTTP request, the original 
request parameters must be preserved by the container for use if, on 
successful authentication, it redirects the call to the requested resource."

It seems as if the request parameters are not being preserved by the 
container.  After a successful login the container forwards me to the target 
URL (a JSP page).  The JSP page executes the following code:

Enumeration params = request.getParameterNames();
while (params.hasMoreElements())
{
 String paramKey = (String)params.nextElement();
 String paramVal = request.getParameter(paramKey);
 System.out.println(paramKey + " = " + paramKey);
}

which I would expect to atleast see printed out:

j_username = <some val>
j_password = <some val 2>

but in fact these request parameters are not printed out and thus not part of 
the request.

A bit of digging in the source revealed that in the method

authenticate(HttpRequest,HttpResponse,LoginConfig)

of class org.apache.catalina.authenticator.FormAuthenticator, the code is 
executing HttpResponse.sendRedirect(String url) in order to forward the user 
to the appropriate page.  A sendRedirect() will wipe out all of the original 
request parameters.

I think in order to preserve the parameters the sendRedirect() needs to be 
replaced by HttpRequest.getServletDispatcher().forward().

Has anyone else seen this behavior and is my claim valid?

Thanks,
  Al



--
Open WebMail Project (http://openwebmail.org)


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Servlet Spec interpretation FORM-based authentication

Posted by "Craig R. McClanahan" <cr...@apache.org>.

On Tue, 12 Nov 2002, Algirdas P. Veitas wrote:

> Date: Tue, 12 Nov 2002 16:04:36 -0700
> From: Algirdas P. Veitas <av...@mail.allesta.com>
> Reply-To: Tomcat Developers List <to...@jakarta.apache.org>
> To: Tomcat Developers List <to...@jakarta.apache.org>
> Subject: Re: Servlet Spec interpretation FORM-based authentication
>
> Craig,
>
> Thank you for clearing this up.  Here is what we are ultimately
> trying to do given our requirements.
>
> We need to introduce the concept of a domain when authenticating users.
> Meaning "jdoe" in "Domain X" is not the same user as "jdoe" in "Domain Y".
>
> Thus, we would like to add another input tag into the j_security_check
> form so that the user can specify their respective domain.
>
> Given the current implementation in the FormAuthenticator, is their any way
> that we can gain access to the "domain" parameter after Catalina performs
> authentication while maintaining conformity to the servlet specification?
>

The set of fields on a form login page are defined in the servlet spec, so
adding extra fields beyond j_username and j_password would break
compatibility with every other servlet container.  Obviously, you can make
that kind of a change in your own copy of Tomcat, but it would be
problematic to do things like that in the standard release.

How most people deal with the issue you raise is to combine the username
and the domain (in your scenario) into the j_username field of the login
(perhaps with usernames like "jdoe@domainx" and "jdoe@domainy" or
something like that), and disambiguate in the Realm implementation as
needed.  That way, you can use the standard container managed facilities
and still be portable.

> Thanks again,
>
>   Al
>

Craig


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Servlet Spec interpretation FORM-based authentication

Posted by "Algirdas P. Veitas" <av...@mail.allesta.com>.
Craig,

Thank you for clearing this up.  Here is what we are ultimately
trying to do given our requirements.

We need to introduce the concept of a domain when authenticating users.  
Meaning "jdoe" in "Domain X" is not the same user as "jdoe" in "Domain Y".

Thus, we would like to add another input tag into the j_security_check
form so that the user can specify their respective domain.

Given the current implementation in the FormAuthenticator, is their any way 
that we can gain access to the "domain" parameter after Catalina performs 
authentication while maintaining conformity to the servlet specification?

Thanks again,

  Al

> See below.
> 
> On Mon, 11 Nov 2002, Algirdas P. Veitas wrote:
> 
> > Date: Mon, 11 Nov 2002 21:56:46 -0700
> > From: Algirdas P. Veitas <av...@mail.allesta.com>
> > Reply-To: Tomcat Developers List <to...@jakarta.apache.org>
> > To: tomcat-dev@jakarta.apache.org
> > Subject: Servlet Spec interpretation FORM-based authentication
> >
> > Folks,
> >
> > I am running into an issue with FORM-based authentication
> > using 4.1.12 (and 4.0.4).  It seems as if the implementation
> > is not in line with the 2.3 Servlet Specification.  Specifically,
> > the Servlet Spec states:
> >
> > SRV.12.5.3 Form Base Authentication
> > --snip--
> > J2EE.12.5.3.1 Login Form Notes
> > --snip--
> > "If the form based login is invoked because of an HTTP request, the 
original
> > request parameters must be preserved by the container for use if, on
> > successful authentication, it redirects the call to the requested 
resource."
> >
> > It seems as if the request parameters are not being preserved by the
> > container.  After a successful login the container forwards me to the 
target
> > URL (a JSP page).  The JSP page executes the following code:
> >
> > Enumeration params = request.getParameterNames();
> > while (params.hasMoreElements())
> > {
> >  String paramKey = (String)params.nextElement();
> >  String paramVal = request.getParameter(paramKey);
> >  System.out.println(paramKey + " = " + paramKey);
> > }
> >
> > which I would expect to atleast see printed out:
> >
> > j_username = <some val>
> > j_password = <some val 2>
> >
> > but in fact these request parameters are not printed out and thus not 
part of
> > the request.
> >
> 
> You are making an incorrect assumption.  It is the *original* request
> 
> (i.e. the one to a protected resource when the user wasn't logged in,
>  and therefore triggered the login) that is saved, and that original 
> request is "replayed" once the login has been completed successfully.
> 
> >From the user viewpoint, and from your application's viewpoint, the flow
> of events is *exactly* like BASIC authentication works -- in between
> regular requests, the login page (form-based) or popup (BASIC) is
> displayed, then the request that triggered the login is executed.  After
> login has been completed, you'll see that getRequestUser() starts
> returning the logged-in username, but from the app you're not able 
> to see the password.
> 
> The actual saving and restoring occurs in
> org.apache.catalina.authenticator.FormAuthenticator.
> 
> > A bit of digging in the source revealed that in the method
> >
> > authenticate(HttpRequest,HttpResponse,LoginConfig)
> >
> > of class org.apache.catalina.authenticator.FormAuthenticator, the code is
> > executing HttpResponse.sendRedirect(String url) in order to forward the 
user
> > to the appropriate page.  A sendRedirect() will wipe out all of the 
original
> > request parameters.
> >
> > I think in order to preserve the parameters the sendRedirect() needs to be
> > replaced by HttpRequest.getServletDispatcher().forward().
> >
> > Has anyone else seen this behavior and is my claim valid?
> >
> 
> Whether a forward or redirect is used is a controversial issue, but
> doesn't affect the flow of events that I describe above -- it's a separate
> decision.
> 
> The reason that Tomcat currently uses a redirect here, and when displaying
> welcome pages, is because so many app developers don't understand an
> important issue related to RequestDispatcher.forward() -- it would break
> any relative URL references in the login page (such as images), because
> relative references are resolved, by the browser, against the URL 
> that was originally submitted to (i.e. the protected page).  Using a 
> redirect, the URL from which relative references are resolved is 
> that of the login page itself.
> 
> > Thanks,
> >   Al
> 
> Craig McClanahan
> 
> --
> To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>


--
Open WebMail Project (http://openwebmail.org)


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Servlet Spec interpretation FORM-based authentication

Posted by "Craig R. McClanahan" <cr...@apache.org>.
See below.

On Mon, 11 Nov 2002, Algirdas P. Veitas wrote:

> Date: Mon, 11 Nov 2002 21:56:46 -0700
> From: Algirdas P. Veitas <av...@mail.allesta.com>
> Reply-To: Tomcat Developers List <to...@jakarta.apache.org>
> To: tomcat-dev@jakarta.apache.org
> Subject: Servlet Spec interpretation FORM-based authentication
>
> Folks,
>
> I am running into an issue with FORM-based authentication
> using 4.1.12 (and 4.0.4).  It seems as if the implementation
> is not in line with the 2.3 Servlet Specification.  Specifically,
> the Servlet Spec states:
>
> SRV.12.5.3 Form Base Authentication
> --snip--
> J2EE.12.5.3.1 Login Form Notes
> --snip--
> "If the form based login is invoked because of an HTTP request, the original
> request parameters must be preserved by the container for use if, on
> successful authentication, it redirects the call to the requested resource."
>
> It seems as if the request parameters are not being preserved by the
> container.  After a successful login the container forwards me to the target
> URL (a JSP page).  The JSP page executes the following code:
>
> Enumeration params = request.getParameterNames();
> while (params.hasMoreElements())
> {
>  String paramKey = (String)params.nextElement();
>  String paramVal = request.getParameter(paramKey);
>  System.out.println(paramKey + " = " + paramKey);
> }
>
> which I would expect to atleast see printed out:
>
> j_username = <some val>
> j_password = <some val 2>
>
> but in fact these request parameters are not printed out and thus not part of
> the request.
>

You are making an incorrect assumption.  It is the *original* request
(i.e. the one to a protected resource when the user wasn't logged in, and
therefore triggered the login) that is saved, and that original request is
"replayed" once the login has been completed successfully.

>From the user viewpoint, and from your application's viewpoint, the flow
of events is *exactly* like BASIC authentication works -- in between
regular requests, the login page (form-based) or popup (BASIC) is
displayed, then the request that triggered the login is executed.  After
login has been completed, you'll see that getRequestUser() starts
returning the logged-in username, but from the app you're not able to see
the password.

The actual saving and restoring occurs in
org.apache.catalina.authenticator.FormAuthenticator.

> A bit of digging in the source revealed that in the method
>
> authenticate(HttpRequest,HttpResponse,LoginConfig)
>
> of class org.apache.catalina.authenticator.FormAuthenticator, the code is
> executing HttpResponse.sendRedirect(String url) in order to forward the user
> to the appropriate page.  A sendRedirect() will wipe out all of the original
> request parameters.
>
> I think in order to preserve the parameters the sendRedirect() needs to be
> replaced by HttpRequest.getServletDispatcher().forward().
>
> Has anyone else seen this behavior and is my claim valid?
>

Whether a forward or redirect is used is a controversial issue, but
doesn't affect the flow of events that I describe above -- it's a separate
decision.

The reason that Tomcat currently uses a redirect here, and when displaying
welcome pages, is because so many app developers don't understand an
important issue related to RequestDispatcher.forward() -- it would break
any relative URL references in the login page (such as images), because
relative references are resolved, by the browser, against the URL that was
originally submitted to (i.e. the protected page).  Using a redirect, the
URL from which relative references are resolved is that of the login page
itself.


> Thanks,
>   Al

Craig McClanahan


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>