Session in two or more WAR

A servlet in WAR_A talk with a browser ,the servlet record some status,such as username,login success or failed.

Then,the browser go to another servlet in WAR_B,

How can the servlet in WAR_B get the status made by the servlet in WAR_A a moments ago.

In some application on web,such as WAR_A work for logining,WAR_B work for other working only who have logined successed can access.

My english is not well,Sorry.

[456 byte] By [TomXu] at [2007-9-26 11:24:17]
# 1

Tom,

Each war (war_a and war_b) has its own servlet context object. When the user accesses another web-application, a new session object tied to the new servlet context is created. Therefore, it is not possible to share information between war files through session objects :(

Here is a quote from the servlet v2.3 spec.'s SRV.7.3 Session Scope section.

"HttpSession objects must be scoped at the application (or servlet context) level.

The underlying mechanism, such as the cookie used to establish the session, can be the same for different contexts, but the object referenced, including the attributes in

that object, must never be shared between contexts by the container.

To illustrate this requirement with an example: if a servlet uses the

RequestDispatcher to call a servlet in another web application, any sessions

created for and visible to the callee servlet must be different from those visible to

the calling servlet."

Sorry to give a negative answer, but that is unfortunately what the Servlet and J2EE spec. require.

Packaging them within a singe war file may be your only option. Some app. servers provide a way around this problem, e.g. iPlanet, but the solution is specific to that app. server. Please refer to your app. server documentation for more information.

If anyone has a solution to this problem, I'd be interested. One possibility is that the sessions within the same "J2EE" application (different from "web" application) can be shared. But that is not how I interpreted the servlet specification. Perhaps I am wrong.

-k

ksundar2 at 2007-7-2 0:33:58 > top of Java-index,Other Topics,Patterns & OO Design...
# 2

Thank you.

Now , I resolve the question by a pool way:

in a servlet in WAR_A,get the login parameter,such as username,password, if it is a right user,login succeed,do:

////////////

request.sendRedirect("servletInWAR_B?user=user&password=password")

////////////

It looks like a stupid idea.Is it?

TomXu at 2007-7-2 0:33:58 > top of Java-index,Other Topics,Patterns & OO Design...
# 3

There is a security issue with this approach, because the query string is visible to the user. If you could simulate a POST to the second servlet, you can get around this problem.

There are other ways to handle this problem.

1. Save an authentication cookie for the web site. Any servlet can read the cookie back to see if the user has been authenticated. If you want to store the password, you should consider encryption of these values. Since cookies are based on URL, they are not bound by the J2EE limitations.

2. Catch the request before it gets to the servlet and authenticate there. This way, servlets are out of the authentication responsibility completely. The mechanism that NAS (and iPlanet, I assume) provides is called NSAPI. If you understand CGI and HTTP protocol, you'll understand how this works.

3. Store the session id in a cookie and in a local db with all the information associated with the session. In the second servlet, read the cookie back and then lookup the session info from the database.

4. Simulate POST instead of GET to the other servlet. Then, the sensitive information is not in the query string.

Hope this helps.

-k

ksundar2 at 2007-7-2 0:33:58 > top of Java-index,Other Topics,Patterns & OO Design...
# 4

You could try setting what ever information into cookies. As they are sent to the server every time, the cookie information is avaiable to the servlet irrespective of which war file it was deployed from.

But this may not be such a good idea if you have lot of information and it is also limited to sharing information in the form of strings.

kotakishore at 2007-7-2 0:33:58 > top of Java-index,Other Topics,Patterns & OO Design...
# 5
You could simply cache the value in a static HashMap or something (only if you are not running your applications within a clustered environment).
apdattani at 2007-7-2 0:33:58 > top of Java-index,Other Topics,Patterns & OO Design...
# 6

There is another way is using J2EE Realm to login the user, then you can get login user from any Servlets or EJBs by getUserPrinciple() or getCallerPrinciple(), whatever the Servlets or EJBs are deployed within the same ear file or not. But all of the ear files must deployed under the same domain.

zhangyn at 2007-7-2 0:33:58 > top of Java-index,Other Topics,Patterns & OO Design...