Craig Berry wrote:

> Hi, all,
>
> I'm attempting to implement a restricted-access
> scheme using JRun.  The idea is for the entire
> subtree under a top-level web dir -- call it "/gated/" --
> to require login to access.  If the user were not
> logged in (as indicated in a session variable), it
> would redirect to the login page, another .jsp.

After researching several approaches, I have finally settled on the following 
approach.  I would like to hear how others are solving this problem.

1. User accesses GuardedPage.jsp via

    http://localhost/path/to/GuardedPage.jsp

2.  GuardedPage.jsp includes a login checking page:

<!--#include file="/admin/" file="LoginChecker.jsp" -->

Every page that needs to be login-protected should include this file (which, depending 
on how your site is set up, may be every page.)

3. LoginChecker.jsp accesses a bean that does the login checking:

<USEBEAN lifespan="session" name ="loginChecker" type="package.LoginChecker">
<setfromrequest beanproperty = "*">
</USEBEAN>

4. The LoginChecker bean has a property 'loggedIn'.  (It also has properies for 
Username and Password, and a processRequest() method, which are used later).

LoginChecker.jsp checks the value of the loggedIn property.  If it is not true (i.e., 
the user is not logged in), a login page is displayed:

<excludeif property ="loginChecker:loggedIn" value = "true">

<FORM action="/servlet/DBAccess/path/to/GuardedPage.jsp" method="post">
Username: <input name="userName" size="15" maxlength="15" >
Password: <input type="password" name="password" size="15" maxlength="15">
<input type="submit" name="loginUser" value="Submit">
</FORM>

</excludeif>

The first time through, this bean will be 'empty' and the loggedIn property will not 
be set.  The login form will therefore be displayed.

5. There is a little trick in the action clause above.  When the user types in his 
login info and presses submit, the invoked URL is

    /servlet/DBAccess/path/to/GuardedPage.jsp

The action passes through the servlet DBAccess, then continues on to our original 
page.  This servlet does nothing more than attach an open database connection to the 
current session:

    session.putValue("open.connection", connection);

The servlet then picks up the trailing part of the URL with:

    String trailingURL = request.getPathInfo();

It then calls forward() to pass control back to the requested page.  In this example, 
the new page happens to be the same as the page we came from.

    getServletConfig(
          ).getServletContext(
          ).getRequestDispatcher(response.encodeURL(trailingURL)
          ).forward(request,response);

6. Now we are back to our original page and the logginChecker bean gets invoked again. 
 Because of the:

    <setfromrequest beanproperty = "*">

in the loginChecker USEBEAN tag, and because our username and password field names in 
the LoginChecker.jsp page match our bean's property names, the username and password 
that the user typed in get 'magically' populated in the corresponding properties of 
the bean.

7. The LoginChecker bean has a processRequest() method which checks to see if a 
username and password has been supplied.  If so (and if we are not logged in), it 
performs a database lookup to log the user in.  If the lookup is successful, the 
loggedIn property is set to true.

8. We are finally back to our GuardedPage.jsp page.  It will probably not want to 
display itself unless the user is logged in.  The page should therefore only be 
included if loggedIn is true:

<includeif property="loginChecker:loggedIn" value="true" >

The contents of GuardePage.jsp are displayed only if loggedIn is true.

</includeif>

We're done!  GuardedPage.jsp is only displayed if the user is logged in.  If the user 
is not logged in, a login page is displayed, which if successful, returns the user to 
the original page.

9.  There is one small cleanup which is needed in Step 4.  As coded above, a 
passthrough servlet is used to attach a database connection to the session.  If the 
user repeatedly fails to login, the servlet prefix will get repeatedly pre-pended to 
the URL.  Furthermore, the 'current page' is hardcoded into the LoginChecker.jsp page 
which restricts it's reusability.  A little JavaScript fixes both of these problems.  
The following JavaScript should be used in place of the <FORM> tag in Step 4. above.

    <script language="JavaScript">
    <!--
    if (document.location.pathname.indexOf("/servlet/package.DBAccess") == 0)
        document.write(
                '<FORM action="' +
                    document.location.pathname +
                    '"method="post">');
    else
        document.write(
                '<FORM action="/servlet/package.DBAccess' +
                   document.location.pathname +
                   '" method="post">');
    //-->
    </script>


begin:vcard
n:Cobb;Christopher
tel;cell:703-909-7550
tel;fax:703-648-7475
tel;work:703-648-6725
x-mozilla-html:TRUE
org:Powerhouse Technologies, Inc.
adr:;;;;;;
version:2.1
email;internet:[EMAIL PROTECTED]
title:SW Architect
fn:Christopher Cobb
end:vcard

Reply via email to