Reputation: 9400
I am using a stateful EJB for keeping my login information:
@Stateful
public class SecurityService {
private static final Logger log4jLogger = Logger.getLogger(SecurityService.class);
@Inject UtenteDao utenteDao;
@Inject AutorizzazioneDao autorizzazioneDao;
private Utente utenteCorrente;
private Negozio negozioCorrente;
public SecurityService() {
}
public boolean authenticate() {
boolean result = false;
Principal principal = FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();
if (principal!=null) {
utenteCorrente = utenteDao.findByUsername(principal.getName());
}
if (negozioCorrente!=null && utenteCorrente!=null) {
Autorizzazione a = autorizzazioneDao.cercaPerNegozioAndUtente(negozioCorrente, utenteCorrente);
result = a!=null;
}
return result;
}
// ... }
My JSF login page is controlled by:
@Named
@RequestScoped
public class LoginController {
@Inject private SecurityService securityService;
private String username;
private String password;
private Negozio negozio;
public void login() throws IOException {
FacesContext context = FacesContext.getCurrentInstance();
ExternalContext externalContext = context.getExternalContext();
HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();
try {
if (request.getUserPrincipal() != null) {
request.logout();
}
request.login(username, password);
securityService.setNegozioCorrente(negozio);
if (!securityService.authenticate()) {
throw new ServletException("Utente non abilitato.");
}
externalContext.redirect("/pippo/");
} catch (ServletException e) {
e.printStackTrace();
context.addMessage(null, new FacesMessage("Accesso Negato"));
}
}
public void logout() throws IOException {
//...
}
public String getLoggedUsername() {
Utente utenteCorrente = securityService.getUtenteCorrente();
String fullName = "";
if (utenteCorrente!=null) {
fullName = utenteCorrente.getNomeCompleto();
} else {
System.out.println("Utente NULLO");
}
return fullName;
}
//...
}
My users actually can login the way I want (programmatic security with some adds from my domain).
The problem I have is in the next page, when you're already logged in. I want to display in all pages header "Welcome! You're logged in as #{loginController.loggedUsername}
.
I keep getting a null securityService.getUtenteCorrente()
.
SecurityService EJB behaves like a Stateless session bean! I want to know whether I am misunderstanding something about the Stateful EJBs, or I just omitted something for this to work as I expect.
My goal is just to have a "session-wide" bean for keeping user state. Is a EJB necessary or can I just use a SessionScoped JSF ManagedBean?
Upvotes: 1
Views: 1372
Reputation: 76719
LoginController
is request-scoped and your SecurityService
is dependent-scoped (for all purposes it is not session-scoped unless you specify it as such). Therefore, when the second JSF page references the LoginController
in a EL expression, a new instance of LoginController
would be created that would have a reference to a different instance of the SecurityService
SFSB.
If you need to access the original SecurityService
instance, you should mark it as @SessionScoped
so that clients like the LoginController
can access them across requests. But then, you might also want to consider why you need a @Stateful
annotation in the first place, since this task could be done by an @SessionScoped
managed bean. You don't really need a SFSB to store a reference to your User/Principal objects.
Upvotes: 4
Reputation: 4211
In order to be managed session beans must be declared using the @EJB
annotation or looked up using the JNDI, the way you inject it just gives you a plain object not managed by the app server, in fact you create a new object any time you use it.
Upvotes: -2