Joysn
Joysn

Reputation: 1029

Redirect not working in JSF2 navigation rule after logout

I want to redirect a user to a start view when he clicks the logout button. The logout is done correctly, and after the start view is requested the user is presented a login page. So far so good, its what i want because the start view is protected and i intercept with a phase listener which redirects to the login page.

Logout action:

public String logout() {

    FacesContext context = FacesContext.getCurrentInstance();
    ExternalContext externalContext = context.getExternalContext();

    // invalidate session
    Object session = externalContext.getSession(false);
    HttpSession httpSession = (HttpSession) session;
    httpSession.invalidate();

    // let the navigation rule decide where to go...
    return null;
}

Faces navigation rule:

<navigation-rule>
    <navigation-case>
        <from-action>#{loginBean.logout}</from-action>
        <to-view-id>/faces/index.xhtml</to-view-id>
        <redirect />
    </navigation-case>
</navigation-rule>

ForceLoginListener:

@Override
public void beforePhase(PhaseEvent event) {

    FacesContext context = FacesContext.getCurrentInstance();

    // extract view id from original request
    String viewId = context.getViewRoot().getViewId();

    if (// viewId is an 'protected' view AND not logged in //) {

        Application app = context.getApplication();

        // redirect to the login view
        ViewHandler viewHandler = app.getViewHandler();
        UIViewRoot viewRoot = viewHandler.createView(context, Constants.LOGIN_VIEW);
        context.setViewRoot(viewRoot);

    }

}

@Override
public void afterPhase(PhaseEvent event) {
}

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

The problem i have now is that the URL which is visible to the user is not the start view nor the login view, it is the view which was active just the moment before the user pressed the logout button.

I thought the redirect in the navigation rule should do the trick as it does for all my other navigation cases, but in this case it does not work. Does anybody have an idea why?

Thanks in advance.

Upvotes: 1

Views: 3498

Answers (2)

BalusC
BalusC

Reputation: 1109532

Your strange ForceLoginListener approach needs to be replaced by a normal servlet filter.

Upvotes: 1

Elias Dorneles
Elias Dorneles

Reputation: 23896

I don't really understand what is happening exactly in your case, but you could just change your logout action to redirect using the externalContext, and eliminate all the fuss with navigation rules:

public void logout() throws IOException {
    FacesContext context = FacesContext.getCurrentInstance();
    ExternalContext externalContext = context.getExternalContext();

    // invalidate session
    Object session = externalContext.getSession(false);
    HttpSession httpSession = (HttpSession) session;
    httpSession.invalidate();

    // redirect to your login view:
    externalContext.redirect(Constants.LOGIN_VIEW);
}

Upvotes: 0

Related Questions