Previous Contents Index Next |
iPlanet Application Server Developer's Guide |
Chapter 12 Creating and Managing User Sessions
This chapter describes how to create and manage a session that allows users and transaction information to persist between interactions.This chapter contains the following sections:
Introducing Sessions
Introducing Sessions
The term user session refers to a series of user application interactions that are tracked by the server. Sessions are used for maintaining user specific state, including persistent objects (like handles to EJBs or database result sets) and authenticated user identities, among many interactions. For example, a session could be used to track a validated user login followed by a series of directed activities for a particular user.The session itself resides in the server. For each request, the client transmits the session ID in a cookie or, if the browser does not allow cookies, the server automatically writes the session ID into the URL.
The iPlanet Application Server supports the servlet standard session interface, called HttpSession for all session activities. This interface enables you to write portable, secure servlets.
Additionally, the iPlanet Application Server provides an additional interface, called HttpSession2, which provides support for a servlet security framework, as well as, sharing sessions between servlets and older iPlanet Application Server components (that is, AppLogics).
Behind the scenes, there are two session styles, distributable and local. The main difference between them is that distributable sessions, as the name implies, can be distributed among multiple servers in a cluster, while local sessions are sticky (that is, bound to an individual server). Sticky load balancing is automatically set for application servlets configured to use the local session model. You determine which session style to use in the application configuration file. For more information about session-related elements in the application configuration file, see Chapter 11 "Packaging for Deployment."
Sessions and Cookies
A cookie is a small collection of information that can be transmitted to a calling browser, which retrieves it on each subsequent call from the browser so that the server can recognize calls from the same client. A cookie is returned with each call to the site that created it, unless it expires.Sessions are maintained automatically by a session cookie that is sent to the client when the session is first created. The session cookie contains the session ID, which identifies the client to the browser on each successive interaction. If a client does not support or allow cookies, the server rewrites the URLs where the session ID appears in the URLs from that client.
Sessions and URL Rewriting
There are two situations in which the iPlanet Application Server plugin performs implicit URL rewriting:
When a response comes back from the iPlanet Application Server; if implicit URL rewriting has been chosen, the plugin rewrites the URLs in the response before passing the response on to the client.
This section includes the following topics:When the request given by a client need not be sent to the iPlanet Application Server and can be served on the web server side. Such requests may occur in the middle of a session and the response may need to be rewritten.
Supported Tags and Attributes
Supported Tags and Attributes
The following tags and attributes are supported for URL rewriting. All of them are case insensitive with respect to the plugin.
The following sections provide additional detail about each of the tags.
The URL mentioned in the href attribute of this tag is rewritten with the cookies.
The URL can have a query string.
The URL must be enclosed in double or single quotes.
The URL must not start with a # character.
Cookies are rewritten just after the end of the URI. If the URL already has a query string, it is placed after the cookies.
AREA
The URL mentioned in the href attribute of this tag is rewritten.
No action is taken for nohref.
FORM
FRAME
The URL pointed to by the SRC attribute of this tag is rewritten.
FRAMESET and NOFRAMES are not processed.
GO
The URL pointed to by the href attribute of this tag is rewritten with the cookies.
The URL can have a query string.
The URL must be enclosed in double or single quotes.
The URL must not start with a # character.
Cookies are rewritten just after the end of the URI. If the URL already has a query string, it is placed after the cookies.
IMG
ONENTERBACKWARD
This is not a tag, but an attribute of WML tags such as CARD and ONEVENT.
ONENTERFORWARD
This is not a tag, but an attribute of WML tags such as CARD and ONEVENT.
ONPICK
This is not a tag, but an attribute of the WML tag OPTION.
ONTIMER
This is not a tag, but an attribute of WML tags such as CARD and ONEVENT.
The URL Rewriting Process
The URL rewriting process of the plugin happens in two stages:
Response Header Processing
For requests that are not sent to the iPlanet Application Server, only response body processing is done.When the plugin receives a request, it checks if there is a query string. If there is one, the plugin extracts the iPlanet Application Server cookies that were encoded in a previous response. These cookies start with the prefix GXHC_. These cookies are stored in two data structures, referred to here as QueryCookies and FormCookies. In the former, the cookies are stored in a query string form. In the latter, they are stored in a format that is suitable for the HTML FORM tag. Currently, the cookies in QueryCookies are used to rewrite all the tags except FORM.
Here is an example of the cookies in QueryCookies:
GXHC_GX_jst=d1f1943e55096164&gx_session_id_=74cd83f757b5c8f6;
Here is an example of the cookies in FormCookies:
<INPUT NAME=" GXHC_GX_jst" TYPE=HIDDEN VALUE="d1f1943e55096164" </INPUT><INPUT NAME=" GXHC_ gx_session_id_" TYPE=HIDDEN VALUE="74cd83f757b5c8f6" </INPUT>
These cookies are extracted and stored, to be used in the rewriting of the subsequent responses.
Response Header Processing
The response from the iPlanet Application Server comes to the plugin in the HTTP response format. The plugin first processes the headers of this response using the following algorithm.
The plugin counts the number of Set-Cookie headers in the response and uses this number to allocate space for a data structure referred to as ResponseCookies. For each Set-Cookie header in the response, the remaining steps are performed.
When the processing of headers finishes, all the old cookies are in QueryCookies or FormCookies and all the new ones are in ResponseCookies. The former are ready to be encoded in the response URLs, but the latter must be converted to such a format.If there is a domain attribute, its value is extracted.
If the cookie is already present in QueryCookies or FormCookies, one of the following occurs:
If the incoming cookie has a domain, the cookie in QueryCookies or FormCookies may have come with its own domain, which was lost when it was used for URL rewriting. Since it has come (again) with a domain, it is treated as a new cookie. The flag treatAsNew is set to TRUE and the cookie is removed from QueryCookies or FormCookies.
If the cookie is not present in QueryCookies or FormCookies, the cookie is brand new, and treatAsNew is set to TRUE.If the incoming cookie does not have a domain associated with it, its value is checked against the value of the same cookie in QueryCookies or FormCookies.
If the incoming cookie has a domain, one of the following occurs:
It is validated using the following rules (from RFC 2109):
If domainOK is TRUE and treatAsNew is TRUE, the incoming cookie is either brand new or an old cookie with a new value. Its name, value, and domain are added to the data structure ResponseCookies.
The incoming cookie does not have a domain. The cookie will be used for URL rewriting, and domainOK is set to TRUE.
- If the domain satisfies these rules, the cookie will be used for URL rewriting, and the domainOK flag is set to TRUE. Otherwise, domainOK is set to FALSE.
Response Body Processing
This stage is reached after the response headers are sent to the client. The body of the response is parsed. The plugin looks for the tags described in the section "Supported Tags and Attributes." It performs the following checks for these tags.
The URL is checked to see if it is absolute or relative. Absolute URLs start with a protocol and look something like this: http://machine.website.com. If the URL is absolute, the host (machine.website.com) is extracted.
The plugin must select cookies from ResponseCookies and convert them to a form that can be used for URL rewriting, referred to as NewCookies. The format used for all the tags except FORM is identical to the QueryCookies format. For FORM, the FormCookies format is used.
Each cookie in ResponseCookies is added or not added to NewCookies according to this decision tree:
If the response URL to be rewritten is absolute, one of the following occurs:
The cookies in NewCookies are always encoded in the response URL. The cookies in QueryCookies and FormCookies are also encoded in the response URL under these conditions:
If the cookie has a domain and it is part of the host name in the response URL, it is added to NewCookies.
If the response URL to be rewritten is relative, one of the following occurs:If the cookie does not have a domain, the host name in the response URL is compared to the one in the request. If they are the same, the cookie is added to NewCookies.
The Location Header
Sometimes a request may be redirected to a different URL by sending back the HTTP header Location in the response. The URL associated with this header is also rewritten. The technique used to encode the URL is the same as the one used in response body processing. However, this rewriting is done as part of response header processing. By the time the Location header is encountered, all the valid cookies have been collected in ResponseCookies. If there is a query string in the URL, it is extracted and saved. The cookies in QueryCookies are added first, if necessary. Then the cookies selected from ResponseCookies are appended. Finally, the original query string is appended.
Order of the Cookies
All encoded cookies precede the query string.The order in which the cookies are encoded in the response URL is dependent on the order in which they arrive as part of the response. Any new cookie in a subsequent request is appended to the cookies list. However, if a cookie is redefined in a subsequent response, it is deleted from its position and added to the end of the cookies list.
For example, suppose the response for a request comes with these cookies:
Set-Cookie c1=v1
Set-Cookie c2=v2
Set-Cookie c3=v3The cookies are encoded as follows:
This order is used for all subsequent responses. All new cookies are appended.
However, suppose c2 is redefined in a subsequent request as follows:
In this case, the format is changed as follows:
Sessions and Security
The iPlanet Application Server security model is based on an authenticated user session. Once a session has been created the application user is authenticated (if used) and logged in to the session. Each interaction step from the servlet that receives an EJB request, generates content to a JSP to format the output and is aware the user is properly authenticated.Additionally, you can specify that a session cookie is only passed on a secured connection (that is, HTTPS), so the session can only remain active on a secure channel.
For more information about security, see Chapter 13 "Writing Secure Applications."
How to Use Sessions
To use a session, first create a session using the HttpServletRequest method getSession(). Once the session is established, examine and set its properties using the provided methods. If desired, set the session to time out after being inactive for a defined time period or invalidate it manually. You can also bind objects to the session which store them for use by other components.This section describes the following topics:
Creating or Accessing a Session
Creating or Accessing a Session
To create a new session or to gain access to an existing session, use the HttpServletRequest method getSession(), as shown in the following example:HttpSession mySession = request.getSession();
getSession() returns the valid session object associated with the request, identified in the session cookie which is encapsulated in the request object. Calling the method with no arguments, creates a session if one does not already exist which is associated with the request. Additionally, calling the method with a Boolean argument creates a session only if the argument is true.
The following example shows the doPost() method from a servlet which only performs the servlet's main functions, if the session is present. Note that, the false parameter to getSession() prevents the servlet from creating a new session if one does not already exist:
public void doPost (HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException
{
if ( HttpSession session = req.getSession(false) )
{
// session retrieved, continue with servlet operations
}
else
// no session, return an error page
}
}
Note The getSession() method should be called before anything is written to the response stream. Otherwise the SetCookie string is placed in the HTTP response body instead of the HTTP header.
For more information about getSession(), see the Java Servlet Specification v2.2.
Examining Session Properties
Once a session ID has been established, use the methods in the HttpSession interface to examine session properties, and methods in the HttpServletRequest interface to examine request properties that relate to the session.Table 12-2 shows the methods to examine session properties.
String mySessionID = mySession.getId();
if ( mySession.isNew() ) {
log.println(currentDate);
log.println("client has not yet joined session " + mySessionID);
}Table 12-3 shows the methods to inspect request object properties that relate to the session:
if ( request.isRequestedSessionIdValid() ) {
if ( request.isRequestedSessionIdFromCookie() ) {
// this session is maintained in a session cookie
}
// any other tasks that require a valid session
} else {
// log an application error
}
Binding Data to a Session
You can bind objects to sessions in order to make them available across multiple user interactions. The following HttpSession methods provide support for binding objects to the session object:
Binding Notification with HttpSessionBindingListener
Some objects require you to know when they are placed in or removed from, a session. To obtain this information, implement the HttpSessionBindingListener interface in those objects. When your application stores or removes data with the session, the servlet engine checks whether the object being bound or unbound implements HttpSessionBindingListener. If it does, the iPlanet Application Server notifies the object under consideration, through the HttpSessionBindingListener interface, that it is being bound into or unbound from the session.
Invalidating a Session
Specify the session to invalidate itself automatically after being inactive for a defined time period. Alternatively, invalidate the session manually with the HttpSession method invalidate().
Tip The session API does not provide an explicit session logout API, so any logout implementation must call the session.invalidate() API.
Invalidating a Session Manually
To invalidate a session manually, simply call the following method:All objects bound to the session are removed.
Setting a Session Timeout
Session timeout is set using the ias-specific Deployment Descriptor. For more information, see the session-info element in Chapter 11 "Packaging for Deployment."
Controlling the Session Type
iPlanet Application Server provides for types of sessions, lite and distributed:
The lite session is a fast, single process implementation of HttpSession. It should be used in all situations where speed is of utmost importance, and where no distribution of session data is required. This is the simplest form of HttpSession.
To control the session type, set the appropriate elements in the iPlanet Application Server specific XML file. For more information, see the session-info element in Chapter 11 "Packaging for Deployment."The distributed session is a robust and scalable implementation of the HttpSession API. It uses the Application Server's distribution facilities, thus enabling failover and load-balancing capabilities. It is somewhat slower than the lite session because of the overhead of network backup.
Sharing Sessions in a Distributed Environment
iPlanet Application Server 6.5 allows the sharing of the same session object with concurrent requests in the same JVM. The following list describes the processes followed by iPlanet Application Server:
Whenever there is a request accessing a session, it will increment a counter.
Whenever there is a first mutable access to the session, the Dsync lock will be triggered, and the locking thread's reference is stored in the session.
The session's state is refreshed from Dsync just after the lock.
Every request while going out will decrement the counter, as well as saving the session.
If the request going out was the one that had originally locked the session, then it waits for all the others requests to go out before the completion of servletrunner.execute().
When all the requests for the session go out, the locking thread will unlock the session and leave.
- This request has been streamed out by the time it reaches this wait. The locking thread needs to wait as it is the only one with the authority to unlock.
In case the session gets invalidated in between, the locking thread is asked to release the lock immediately, as there is not going to be any requirement for backend consistency from that point onwards.
Sharing Sessions with AppLogics
Servlet programmers can use the iPlanet Application Server interface, HttpSession2 to share distributable sessions between AppLogics and servlets. Sharing sessions is useful when you want to migrate an application from NAS 2.x to iPlanet Application Server 6.5. HttpSession2 interface adds security and direct distributable sessions manipulation.Additionally, if you establish a session in an AppLogic using loginSession() and you want to access the session from a servlet, you must call the setSessionVisibility() method in the AppLogic class to instruct the session cookie to transmit to servlets as well as AppLogics. Additionally, this must be completed before calling saveSession().
domain=".mydomain.com";
path="/"; //make entire domain visible
isSecure=true;
if ( setSessionVisibility(domain, path, isSecure) == GXE.SUCCESS )
{ // session is now visible to entire domain }For more information about setSessionVisibility(), refer to the AppLogic class in the Foundation Class Reference (Java). For more information about sharing sessions between AppLogics and servlets, see the Migration Guide.
Previous Contents Index Next
Copyright © 2002 Sun Microsystems, Inc. All rights reserved.
Last Updated March 06, 2002