How to invalidate session in JSF 2.0?
Asked Answered
F

4

64

What is the best possible way to invalidate session within a JSF 2.0 application? I know JSF itself does not handle session. So far I could find

private void reset() {
    HttpSession session = (HttpSession) FacesContext.getCurrentInstance()
            .getExternalContext().getSession(false);
    session.invalidate();
}
  1. Is this method correct? Is there a way without touching the ServletAPI?
  2. Consider a scenario wherein a @SessionScoped UserBean handles the login-logout of a user. I have this method in the same bean. Now when I call the reset() method after I'm done with necessary DB updates, what will happen to my current session scoped bean? since even the bean itself is stored in HttpSession?
Footboy answered 11/4, 2011 at 10:14 Comment(0)
Q
128

Firstly, is this method correct? Is there a way without touching the ServletAPI?

You can use ExternalContext#invalidateSession() to invalidate the session without the need to grab the Servlet API.

@ManagedBean
@SessionScoped
public class UserManager {

    private User current;

    public String logout() {
        FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
        return "/home.xhtml?faces-redirect=true";
    }

    // ...

}

what will happen to my current session scoped bean? since even the bean itself is stored in HttpSession?

It will still be accessible in the current response, but it will not be there anymore in the next request. Thus it's important that a redirect (a new request) is fired after invalidate, otherwise you're still displaying data from the old session. A redirect can be done by adding faces-redirect=true to the outcome, as I did in the above example. Another way of sending a redirect is using ExternalContext#redirect().

public void logout() throws IOException {
    ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
    ec.invalidateSession();
    ec.redirect(ec.getRequestContextPath() + "/home.xhtml");
}

Its use is however questionable in this context as using a navigation outcome is simpler.

Quinby answered 11/4, 2011 at 11:25 Comment(3)
@BalusC, what's the difference between ExternalContext#invalidateSession() and HttpSession#invalidate()?Gravamen
@Patrick: Functionally, nothing. They both do exactly the same. ExternalContext#invalidateSession() calls under the covers HttpSession#invalidate() (see also the javadoc link in my answer). Design-technically, the ExternalContext approach is better. You should basically strive to have zero javax.servlet.* imports in any of your JSF related artifacts.Quinby
What about a SSL session? Is it possible to invalidate it? Because I tried unsuccessfully via the suggested methodMobile
C
13
public void logout() {
    FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
}
Cassiecassil answered 19/7, 2012 at 9:57 Comment(0)
L
0

With a "normal" redirect I ended up with a login form (where I was redirecting to) which was not working. I ended up doing a JavaScript update of the document href. Using OmniFaces it's looking like this:

if (!Faces.isAjaxRequest()) {
  throw new FacesException("Ajax request is required");
}
// ... Do logout from your security manager here (we use Shiro)
Ajax.oncomplete("document.location.href='" + url + "'");
Longshoreman answered 1/11, 2023 at 15:11 Comment(0)
C
-1

Frontend code is:

<h:form>
<h:commandLink action="#{userManager.logout()}">
       <span>Close your session</span>
</h:commandLink>
</h:form>

Backend code is:

public String logout() {
    HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
    if (session != null) {
        session.invalidate();
    }
    return "/login.xhtml?faces-redirect=true";  
}
Chilon answered 11/12, 2020 at 11:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.