Reputation: 183
I need a little direction understanding sessions in JSF (2.2.6). I've tried to find some documentation but am still missing something.
I have a @RequestScoped login bean which saves parameters in the session map for reference by other session scoped backing beans. They get the user info when they go through the PostConstruct method and everything works great.
However the logic fails when more than one window is used or the user doesn't logoff and goes directly back to the login page. JSF treats this as the same session and the @PostConstructs are not invoked.
I am pretty sure I could invalidate the session but that doesn't solve the problem of multiple users from different browser windows.
Any guidance or reference sites would be appreciated.
Thanks in advance! John
Upvotes: 1
Views: 1715
Reputation: 7469
session HAS to be same for every browser window, the only exception is when using anonymous mode: i.e. chrome behave like having two browsers opened at the same time.
another way to have multiple sesssions is to use different server name:
http://localhost:8080/app
and http://127.0.0.1:8080/app
may not share a single session.
however sessions never overlaps.
your problem, if i understand right, is when a logged user access login page and re-login, preserving his old session, that's why session beans are not PostConstructed again (independently from window used).
a general solution is to forbid access to login page for logged users. and in general, container will throw an AlreadyAuthenticatedException or similar when user re-login without prior logout.
cut a long story short, just a preliminary example waiting for your code:
@ManagedBean
@SessionScoped
public class UserBean implements Serializable
{
private static final long serialVersionUID = 1L;
private User user;
public boolean isLoggedIn()
{
return user != null;
}
public void login(String username, String password)
{
// maybe you want to check isLoggedIn() and either call logout() or throw an exception
HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
request.login(username, password);
user = someDAO.loadFromDatabase(username);
}
public void logout()
{
// maybe you want to check isLoggedIn() and either throw an exception or do nothing
HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
request.logout();
user = null;
// suggested for another scenario
// request.getSession().invalidate();
}
// getters and setters
}
and
@ManagedBean
@SessionScoped
public class OperationBean implements Serializable
{
private static final long serialVersionUID = 1L;
@ManagedProperty("#{userBean}")
private UserBean userBean;
public void execute()
{
if(!userBean.isLoggedIn())
{
FacesContext.getCurrentInstance().getExternalContext().redirect("login.jsf");
return;
}
User user = userBean.getUser();
// do something
}
// getters and setters
}
with this combination, instead of using OperationBean's @PostContruct i used @ManagedProperty, so that OperationBean contains an always-up-to-date reference to user, without caring multiple re-logins.
Upvotes: 1