Invalidating session with CDI+JSF not working

末鹿安然 提交于 2020-02-03 09:21:15

问题


I'm trying to implement a logout in my application, so I made this:

public String logout(){
    try{
        FacesContext facesContext = FacesContext.getCurrentInstance();  
        ExternalContext ex = facesContext .getExternalContext();  
        ex.invalidateSession(); 
        return "success"; 
    }catch(Exception e){
        return "error";
    }
}

But when I check if the user is logged, it says yes:

public class AuthenticateListener implements PhaseListener {


    @Override
    public void afterPhase(PhaseEvent event) {
        AuthorizedUser authorized = (AuthorizedUser) Util.getHandler("authorized");
        if (authorized.getUser() == null) {
            System.out.println("Not Logged");
        } else {
            System.out.println("Logged");
        }
    }

    @Override
    public void beforePhase(PhaseEvent event) {
        // TODO Auto-generated method stub

    }

    @Override
    public PhaseId getPhaseId() {
        return PhaseId.RESTORE_VIEW;
    }

}

Am I missing something? Shouldn't I get a new instance of AuthorizedUser (sessionScoped) after invalidating my session?

EDIT: Adding the getHandler, if someone needs it ;)

public static Object getHandler(String handlerName) {

    FacesContext facesContext = FacesContext.getCurrentInstance();
    ELContext elContext = facesContext.getELContext();
    ELResolver resolver = facesContext.getApplication().getELResolver();

    Object uh = resolver.getValue(elContext, null, handlerName);
    return uh;
}

回答1:


The session is still available in the current request-response. It's not available anymore in the next request. You need to send a redirect after the invalidate so that the browser will be instructed to send a new request on the given URL.

return "success?faces-redirect=true"; 

Or if you're still using old fashioned navigation cases (the return values namely suggests that; it's strange to have a view with filename "success"), then add <redirect/> to the navigation case instead.

If that still doesn't work, then the bug is in how you're storing the user in session. For example, it's instead actually been stored in the application scope which may happen when you mix CDI @Named with JSF @SessionScoped, or when you assigned the logged-in user as a static variable instead of an instance variable.

See also:

  • How to invalidate session in JSF 2.0?
  • Performing user authentication in Java EE / JSF using j_security_check



回答2:


Use this piece of code inside logout method:

HttpSession oldsession = (HttpSession) FacesContext
                .getCurrentInstance().getExternalContext().getSession(false);
oldsession.invalidate();

This will work. Let me know please if it was helpful for you.



来源:https://stackoverflow.com/questions/10350657/invalidating-session-with-cdijsf-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!