JSF logout using session.invalidate does not clear

2019-02-12 23:01发布

问题:

In my JSF application, I get the name of the currently signed in user like this ...

public String getLoggedInUsername() {
  return FacesContext.getCurrentInstance().getExternalContext().getRemoteUser();
}

... and I check if the user is signed in like this ...

public boolean isSignedIn() {
  return (getLoggedInUsername() != null);
}

... and when the user signs out, I do this ...

public String doLogout() {
  FacesContext facesContext = FacesContext.getCurrentInstance();
  HttpSession httpSession = (HttpSession)facesContext.getExternalContext().getSession(false);
  httpSession.invalidate();
  return "main";
}

My problem is after doLogout(), the getLoggedInUsername() still returns the name of the user that was logged in. What am I supposed to do to make sure getRemoteUser() returns null after logout?

Alternately, is there a better way to get if isSignedIn() than just checking the username?

Thanks! Rob

回答1:

Ensure that you're redirecting the request after invalidating the session. The user principal is resolved based on a session attribute. So when you just forward to the target page (as a JSF navigation case by default does), then it'll still be there in the target page since it uses the same HttpSession reference. A redirect instructs the webbrowser to fire a brand new HTTP request, hereby forcing the server to recreate the HttpSession reference based on the new request.

Add <redirect/> to the navigation case to force JSF to send a redirect. Or when you're already in JSF 2.0, add ?faces-redirect=true to the outcome value.



回答2:

After call "session.invalidate();" , add "request.logout();".

Method invalidate on session object just clean session data.

Method logout on request object establish null as the value returned when getUserPrincipal, getRemoteUser, and getAuthType is called on the request.