0

I've looked at some other threads here and I think I have the general idea of how to use a SessionScoped bean for maintaining a user's logged in state. However, as I am relatively new to JSF 2, I am trying to figure out the best way to use the bean during login and on subsequent pages to render a header/footer (using same page template, but different menus/links depending on login state and non-logged in state).

I have a typical JSF2 login form that calls a backing bean (request scoped) login() method. All of that works, and I am going to tie it in to the container security soon as I have a little more time to work on and figure that part out (realms, roles, etc).

In the old pre-JSF (jsp/struts) days, upon login, I'd add an object, usually a user ID Long value that would be easy to replicate across a cluster of sessions and restore a full user object from. This kept the httpsession data minimal (one Long value per user), and regardless of what server a user was routed, I could determine they were logged in and pull up their user object and go from there.

With JSF, I am not sure the right way to do this. I have a SessionScoped bean with a Long userid property. Upon the login() method succeeding, I use the ExternalContext to add the attribute of the SessionScoped object, something like:

User user = loginBean.login(username, password);
Session session = new Session();
session.setUserid(user.getId());
externalContext.getSessionMap().put("usersession", session);
externalContext.redirect(originalURL);

The Session is the SessionScoped bean, and it's CDI name is usersession. I hope that is the right way to stick the bean into the HttpSession so it can be used on pages, etc with EL.

The first thing I am not sure of is because the bean is SessionScoped, do I need to put it into the session after creating it in the above code? Or is that done automatically upon creation for me since it's scoped as session?

The second question is.. being picky that I am, I don't want a Session object in the session until the user logs in, even if the userid is null. So on a xhtml page, if I have something like:

<h:panelGroup render="#{usersession.loggedin}"...>

Will that create and put the Session bean into the session the first page that uses that? Or will that Session object not be put into the HttpSession until I do so with my code above? My guess is, if it gets put into the session upon creation, then the use of it on any page will create it and stick it in the session. I am less bothered by this..the object with just the Long property is very little memory use per user on the system, but like I said, I am being picky and more so wanted to understand exactly when a SessionScoped object gets stored into the session.

Thanks.

1 Answers1

0

The first thing I am not sure of is because the bean is SessionScoped, do I need to put it into the session after creating it in the above code? Or is that done automatically upon creation for me since it's scoped as session?

The managed bean is autocreated in the given scope if referenced for the first time in EL by #{beanName} while it's not in the scope yet. So, no, you don't need to do it yourself. Just inject it as managed property in your login bean.

@ManagedProperty("#{usersession}")
private Session session;

// ...

User user = loginBean.login(username, password);
session.setUserid(user.getId());
externalContext.redirect(originalURL);

Will that create and put the Session bean into the session the first page that uses that? Or will that Session object not be put into the HttpSession until I do so with my code above?

It will do that once you reference it for the first time in EL by #{beanName}.


Unrelated to the concrete question, another way is

User user = loginBean.login(username, password);
externalContext.getSessionMap().put("user", user);
externalContext.redirect(originalURL);

and check for the logged-in user as follows

<h:panelGroup rendered="#{not empty user}">

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thank you BalusC.. your reply is what I read in another thread without the part about it being created the first time it's accessed. I suppose it's not a big deal if their is a usersession object in the HttpSession that is not used (they never log in). It's not much in memory to keep it there even if they never log in. What does rendered="#{not empty user}" mean? Is the string 'not empty user' built in to JSF or something? Or is that to be replaced with an actual bean property that returns true or false depending if the user is logged in? – user2520618 Jul 04 '13 at 19:31
  • On a separate note.. in that link to JEE6 container security, the one thing that is not answered (it appears that thread is closed)... if a user tries to access a bookmarked /secured/* page I have it working now where it will take them to a login page. But once they log in using my form auth and my JSF bean code, with a session object stored.. how does the container security use my session object to further allow the user to navigate other /secured/* pages without redirecting them to log in every time? I don't see how you configure the container to no longer check once a user is authenticated? – user2520618 Jul 04 '13 at 19:40
  • Two things to add to this.. first, not sure why but the @ManagedProperty("#{usersession}") did not inject the session object for me. I kept getting NPEs when I tried to log in on the session object. I resorted to using the external context to grab it instead which worked. Second, I found Apache Shiro with your detailed description of how to implement it BalusC and it works great! I had to modify a little bit to use my mysql setup, but it works really well and much easier to work with than the JEE container security stuff. – user2520618 Jul 05 '13 at 17:15