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