1-Feb-05 (Created: 1-Feb-05) | More in 'Howto'

Writing Login Pages in Aspire

This document describes the general phiolosophy of writing a login web page with in Aspire. I want to emphasize that because increasingly user authorization is being handled by such things as portals with single sign on and also enterprise security tools such as Netegrity or via servlet filters while leaving the main framework such as Aspire for painting and updating state.

Having said that, it is also possible that you are an individual developer and you don't want to configure these external tools for this and you just want to use the aspire.jar to accomplish this as well.

If you choose to use HttpAuthentication, Aspire has built in facilities for authentication. But if you want to write your own login page there is a bit of work required on your part, such as creating the web page and authenticating that user etc.

General Phiosophy

The first thing to do is to disable Aspire's HttpAuthentication and its session management in case if the downloaded build has these enabled. When session management is disabled, Aspire will ensure that there is a session all the time for every page. This simple change will allow you access to every page that you develop in Aspire including your login pages.

As a next step your login pages should, on a successful login, set a session variable indicating that a successful login took place.

But that doesn't stop from a user entering a page when he/she is not logged in. To do this you need to write a "BeginRequest" handler that intercepts every request (like a servlet filter) and check for the logged in status. If it is not logged in then you will return a false from this handler after redirecting to the login page.

Other than that you develop login web pages like any other web pages in Aspire.

Now let me consider each of the steps in some detail

Turning off the HttpAuthentication

Make sure the following two settings are turned off


aspire.authentication.userAuthorization=no
aspire.sessionSupport.applySessionManagement=no

Turning off userAuthorization will tell Aspire to stay off the HttpAuthentication. Turning of applySessionManagement will tell Aspire to create a session if one doesn't already exist.

How to login now?

Now design a login page with a login form. Eventually this form will submit a request to the server side for the login to take place. This will look something like this


http://host/your-app/update
?request_name=LoginRequest
&username=abc
&password=xyz

Note that the lines are broken for clarity and readability.

This request then is handled by Aspire on the server side in its usual manner as follows


request.LoginRequest.classname=(your-java-class)

request.LoginRequest.redirectURL=\
/{aspireContext}/display/url=WelcomePageURL

request.LoginRequest.failureRedirectURL.INVALID_LOGIN=\
/{aspireContext}/display/url=YourLoginForm\
&pageStatus=invalid-login\
&viewstate={viewState}

Your java class is called with a hashtable of the incoming parameters. If it succeeds and doesn't throw any exception then the url is rerouted to welcome page with the assumption that the login took place. If an exception is thrown with a message starting with INVALID_LOGIN then the same page is displayed with its view state intact and an error message.

Your java class is responsible for validating the user against the password and also setting the logged in status to true in the session. Aspire has a built in part that can do this for you called AspireLoginPart. With this you can do the following:


request.LoginRequest.classname=com.ai.parts.AspireLoginPart

request.LoginRequest.redirectURL=\
/{aspireContext}/display/url=WelcomePageURL

request.LoginRequest.failureRedirectURL.INVALID_LOGIN=\
/{aspireContext}/display/url=YourLoginForm\
&pageStatus=invalid-login\
&viewstate={viewState}

Source code of AspireLoginPart

To understand what AsprieLoginPart does let us see the source code of this part

AspireLoginPart source code

But in brief here is its functionality

  1. This class is an HttpPart receiving request, response, session, and the rest of the args
  2. Uses Aspire's authentication plug in for validating user login
  3. If it is not a valid user throws an exception whose root cause starts with INVALID_LOGIN
  4. otherwise sets the user variable called "profile_user" in session
  5. Kicks of user logged in event via the HttpEvent Distributor
  6. sets the "aspire.loggedin_status" to true

How to reject

The following lines will allow a private URL to go through only if a login took place


# HttpEvents
request.IHttpEvents.classname=com.ai.servlets.HttpEventDistributor
request.IHttpEvents.eventHandlerList=loginHandler

request.loginHandler.classname=com.ai.servlets.LoginValidator
request.loginHandler.loginPageURL=/{aspireContext}/login/index.html

There are two things going on here. The first set defines a general purporse event distributor for Aspire. This setting allows for distributing such events as begin request, end request as defined in IHttpEvents.

The second setion registers a begin request handler called LoginValidator that intercepts begin requests.

LoginValidator

Take a look at the source code to see what it does

Source code of LoginValidator

But briefly this will reject a URL if a login did not take place. In brief here is the functionality of this LoginValidator

  1. If the user is logged in return true and let the request continue
  2. If not see if the url is a public url using the Aspire's authentication plug in
  3. If it is a public url let it go through
  4. otherwise (private url) redirect user to the page identified by "loginPageURL"

The role of Aspire's authentication plugin

Aspire uses an authentication plug in to answer the following questions as defined by IAuthentication2 interface.

  1. Is this URL a public url?
  2. Given a userid and password do they match?
  3. Given a username is access to this url allowed?

It is quite easy to implement this interface. One of the prebuilt implementations is called a TrivialAuthentication. You can look at its source code that is available in the distributed aspire.jar file.

The following configuration allows TrivialAuthentication to be the chosen authentication plug in. The public urls tell which display urls are public. The request names tell which updates are allowed to be public with out a login.


request.aspire.authentication.authenticationObject.className=\
com.ai.aspire.authentication.TrivialAuthentication

request.aspire.authentication.authenticationObject.publicURLs=\
LoginPageURL

request.aspire.authentication.authenticationObject.publicRequestNames=\
LoginRequest

aspire.authentication.password=aspire

There are two more built in authentication plugins that could prove to be useful in your specific cases. These are

  1. com.ai.aspire.authentication.SimpleDBAuthentication1. This document describes how to use this class for logging from a database.
  2. com.ai.aspire.authentication.UserURLMapAuthorization

Take a look at their source code to see what arguments they take from the configuration file. The first one does database authentication based on an sql statement. The second extends the previous one with an ability to reject or allow a url based on a username.

Further References

1. How to redirect when a session expires in Aspire for Build 20 and above

2. LoginValidator Source code

3. AspireLoginPart source code

4. How to use and configure HttpEvents

5. How to use SimpleDBAuthentication1

6. How to write a login application using Aspire

7. How do you know if you have logged-in in Aspire?

8. How to turn of HttpAuthentication in Aspire to allow a login page?