"L. Turetsky" wrote:
>
> Thank you, Hans! This is *exactly* the solution I was looking for. Now that
> you've said it, it seems brilliantly obvious.

Maybe, but thinking a bit more about this, I'm not sure it's such a good
idea as I first though. Spencer Ridder raised a very important issue in
another mail in this thread, namely the risk of user B inheriting user A's
information.

Say user A fills out a form, say the credit card info needed to purchase
all the stuff in his/her shopping basket, and then leaves long enough
for the session to time out. Next user B comes along and submits the
form, gets redirected to the login form where all the parameter values
are saved as hidden fields. If user B now enters his/her username/password
and clicks Login, he/she will end up submitting the purchase form with
user A's credit card number. Hmmm....

Also, as Spencer said, you may have to save the session state (the shopping
cart) as hidden fields in the purchase form as well to be really sure things
works as planned.

In general, this kind of "remember the original URL and invoke it after
successful login" scheme seems a bit problematic for POST requests. If
you use POST as intended, it's only for requests that change something on
the server. And you want to really make sure you don't change something
someone else started in your own name. I feel that the best thing is to
always redirect to the applications main page if the request that triggered
the login form to be displayed was a POST request, and only invoke the
original URL for GET requests (intended to be harmless according to the
HTTP spec).

A possible way out for POST requests is to keep the current user's name
in a hidden field in the POST form. It will then end up being saved as
a hidden field also in the login form. In the authentication code you
can then check if the new user is the same as the old user, and only forward
to the originally requested URL if they are the same.

> In the thread that's ensued, there's been an argument against over-riding
> the service() method, which echoes a previous thread on this list.
>
> This concerns me, b/c LoginServlet.service() performs all the
> authentication *before* passing the request to super.service(), which in
> turn calls doGet/doPost.
>
> Would it be wiser to simply put the authentication code into doGet() and
> doPost()?

You could put all this code in a utility class instead of using a super
class for all servlets, and let each servlet call the utility class in
doGet()/doPost() instead. But since you always call super.service(), according
to your description below, you're still getting the default behavior.

Hans

> At 08:55 PM 12/15/1999 -0800, Hans Bergsten wrote:
> >"L. Turetsky" wrote:
> >> [...]
> >> I've written two such servlet-based systems in the past, both with the
> >> following design pattern:
> >> All login-required servlets sub-class from an abstract class called
> >> LoginServlet, whose service() method does the following:
> >>         if login info (name&password) is in request, check the info
> >>                 if valid, store a Login object in Session & call
> super.service() (which
> >> calls doGet/doPost)
> >>                 else, show a login screen
> >>         else if user is already logged in (i.e., there is a Login object
> in the
> >> Session), call super.service() (which calls doGet/doPost)
> >>         else, show a login screen
> >> [...]
> >>
> >> When the login screen is presented, all the parameter fields in the request
> >> (except name/password) are encoded in the login form as INPUT
> >> TYPE="HIDDEN", and the FORM ACTION= HttpServletRequest.getRequestURI()
> >> (i.e., the servlet they were trying to access, since it subclasses
> >> LoginServlet). That way, once the login is authenticated, the user's data
> >> is passed to the servlet s/he was trying to access.
> >> [...]
> >> OK, so what's the problem?
> >>
> >> Well, to keep the request un-changed, the login page's FORM METHOD= should
> >> be HttpServletRequest.getMethod(). However, in the case of GET requests,
> >> the resulting URL contains the username and password (e.g.,
> >>
> http://www.myserver.com/servlet/SubClassOfLoginServlet?userName=lenny&passwo
> >> rd=1234567890). Which makes my boss/client unhappy.
> >> As a band-aid fix, I'm turning all requests into POSTs, but that's kind of
> >> "rude", as some sub-class servlets may behave differently in the case of
> >> POST than GET.
> >> [...]
> >> Can anyone think of a work-around or alternative design pattern that would
> >> still allow for the benefits of the system outlined above?
> >
> >I like the approach of preserving the original params as hidden fields,
> >and I agree that you need to invoke the original request with the original
> >method. Browsers treats POST and GET very differently when it comes to
> reloading
> >the page, caching, etc. I haven't tested, but would something like this work.
> >
> >Besides saving all parameters as hidden fields in the login form, you can
> also
> >save the method. The login form itself use POST to avoid the
> username/password
> >in the URL. In the LoginServlet service method you do the authentication as
> >before, but only call super.service() if the original request was a POST.
> >If the original request was a GET, you do a redirect() with all the original
> >parameters instead.
> >
> >Hans
> >--
> >Hans Bergsten           [EMAIL PROTECTED]
> >Gefion Software         http://www.gefionsoftware.com

--
Hans Bergsten           [EMAIL PROTECTED]
Gefion Software         http://www.gefionsoftware.com

___________________________________________________________________________
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff SERVLET-INTEREST".

Archives: http://archives.java.sun.com/archives/servlet-interest.html
Resources: http://java.sun.com/products/servlet/external-resources.html
LISTSERV Help: http://www.lsoft.com/manuals/user/user.html

Reply via email to