Hi all,

I've looked thru the archives (and have been a list subscriber for a few
months) and haven't seen a discussion on this yet, so here goes...

I'm working out what I think is a wise/clever design for a servlet-based
login system.

I've been tasked with writing an extensible membership area for a website.
The idea is that people have to login to access certain pages, and some of
those pages may include dynamic data specific to the logged-in user (e.g.,
what books they've bought in the past). Pretty standard fare, IMO.

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

The nice thing about sub-classing from LoginServlet is that it allows the
specific servlets (and their authors) to concentrate only on their task w/o
any need for understanding how login is done (the basic idea behind
inheritance in general). All they know is that the login info is available
from the Session's Login object, accessible via the static method
Login.getLogin(HttpServletRequest).

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.
This is useful in the case of a user's login session expiring while filling
out a long form, so they don't have to re-enter all the data. For example,
imagine that you login to a site, start filling out a huge form during
which time your login expires. When you submit, you're asked to login
again. In this design, as soon as you login the data you entered into the
form is passed on and you're back on the path you were travelling.

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. (I can't think of a reason why; generally, I either
implement only POST b/c the servlet's action is not idempotent, or I
implement doGet and then make doPost simply call doGet. But LoginServlet
will be sub-classed by other developers, and I can't constrain them this way.)
One potential workaround is to define a doPost() method in LoginServlet
which either calls doGet(Request, Response) or simply redirect to
HttpServletRequest.getRequestURI() + "?" +
HttpServletRequest.getQueryString(). That would solve the situation when a
sub-class only implements doGet(), but not if it implements doGet() and
doPost() differently.

Can anyone think of a work-around or alternative design pattern that would
still allow for the benefits of the system outlined above?

Some people have spoken about the single-servlet model where that servlet
takes a parameter (or PathInfo) specifying an alternate servlet/object to
invoke. That might do as well in this case, but I'm not really
familiar/comfortable with that kind of system.

Thanks in advance,
LT
--
The nice thing about being a cynic is that I enjoy being wrong.

___________________________________________________________________________
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