I'm a little puzzled by that opinion. Here is my take on the subject
(sorry if this is ground that has already been covered):
If you are using J2EE security, then the login information *must* be
maintained by the container. If you are in a web environment, this is
information is going to be automatically associated with an HttpSession
without any special code. As long as the HttpSession is valid, you can
use ejbContext.getCallerPrincipal().getName() from any bean to get the
user identity.
Because of this, there is no reason to force the user to reenter their
credentials if a stateful session bean expires. Stateful sessions
shouldn't be part of the login process; they should acquire their
identity from getCallerPrincipal().
Here is what my setup looks like:
Every "protected" page (JSPs which require authentication and access to
the stateful session object) has this line at the top:
-----
<%@ include file="include/ensure_session.jsp" %>
-----
The file ensure_session.jsp is simply this:
-----
<%@ taglib uri="ejbtags" prefix="ejb" %>
<%@ taglib uri="utiltags" prefix="util" %>
<util:ifInRole role="authenticated" include="false">
<% request.setAttribute("destination",
request.getServletPath()); %>
<jsp:forward page="login_required.jsp" />
</util:ifInRole>
<ejb:useBean id="memberSession"
type="com.similarity.ejb.membersession.MemberSession"
scope="session">
<ejb:useHome id="sessHome"
type="com.similarity.ejb.membersession.MemberSessionHome"
location="java:comp/env/ejb/MemberSessionEJB" />
<ejb:createBean instance="<%= sessHome.create() %>" />
</ejb:useBean>
-----
The login page uses the RoleManager to actually perform the login. To
be 100% platform independant you can use the servlet form authentication
system, but it sucks. I can accept rewriting one method if I ever need
to switch containers. If anyone would like to see what my login page,
submission page, and bean look like, I can post them too.
The ejbCreate method for MemerSession is this:
-----
/**
*/
public void ejbCreate() throws CreateException
{
// Use caller's security Principal name to find the
appropriate Member
String name = ejbContext.getCallerPrincipal().getName();
MemberHome membHome =
(MemberHome)this.getHome("MemberEJB", MemberHome.class);
try
{
this.memb = membHome.findByName(name);
}
catch (Exception ex)
{
// Should never happen, because authentication
uses the same
// database that the Member EJBs do.
throw new CreateException(ex.toString());
}
}
-----
Thus, no matter what, as long as a user is logged in, they can create
(and re-create) a session. My deployment descriptor requires the
"authenticated" role for any method calls on the MemberSession just to
make sure. If the session bean ever times out, it can simply be
recreated.
Acutually, I'm probably not handling this case... I may have to put some
code in ensure_session.jsp to check the validity of the memberSession.
The tag library doesn't appear to check for expired sessions. Looks
like this just simply requires calling getHome() or one of the other
EJBObject methods and checking for java.rmi.NoSuchObjectException. Of
course this would have the effect of touching the session every time a
page is loaded, so the staleness of the stateful session bean would
pretty much follow the HttpSession (eliminating the problem anyways).
Another approach might be to do no extra checking and just simply
recreate the stateful session in the error page (if the error is
java.rmi.NoSuchObjectException). Hmmmm.... that would be annoying to
the user, so maybe touching the stateful session bean on ever page load
would be the best approach.
Comments?
Jeff Schnitzer
[EMAIL PROTECTED]
Unit Test your EJBs: http://www.infohazard.org/junitee
> From: Joshua Goodall [mailto:[EMAIL PROTECTED]]
> Sent: Sunday, November 05, 2000 8:26 AM
> To: Orion-Interest
> Subject: Re: Stateful Session timeout, JSPs
>
> This is an old thread, but I was browsing archives and had a
> contribution
> to make.
>
> Thomas Munro wrote:
>
> > I have a (1) JSP session which stores a reference to (2) a stateful
> > session EJB. If either times out, I want the user to be
> bounced to a
> > page where they have to log in (again). The problem is that the JSP
> > session and the session EJB time out under different
> conditions -- that
> > is to say, merely surfing around the web application will
> keep the JSP
> > session alive, but the EJB is only kept alive by accessing it, which
> > doesn't necessarily happen on every page. Otherwise, I
> could simply set
> > the EJB to timeout after a longer time than the JSP session.
>
> This was discussed and the best suggestion (from Kevin
> Duffey) was to use
> stateless beans and keep all state in the HttpSession.
>
> However, if you are architecturally obliged to use stateful
> beans, part of
> the solution might be to make the bean timeout very long, and set a
> HttpSessionBindingListener (HSBL) attribute in the
> HttpSession (you could
> accomplish this with useBean in session scope). Your HSBL is then
> signalled by the servlet container to cleanly handle the case (e.g.
> calling homeinterface.remove(mysession) ) where the JSP
> session times out
> before the long-lived stateful session bean.
>
> This doesn't make things any prettier if you restart the EJB
> container, or
> if you have to have a short timeout for the session bean, but
> it might fit
> your model.
>
> J
>
> -[ Joshua Goodall
> ]-----------------------------------------------
> -[ Chief Systems Architect, IP R&D ]----- Cook, Geek, Lover
> ------
> -[ [EMAIL PROTECTED] ]---------------
> [EMAIL PROTECTED] --
>
>
>