16 Nisan 2010

Controlling Login by PhaseListener in JSF

I have learned a few things about jsf today.

First thing is to maintain login/logout account control using phase listener. From a number of options to ensure only loggedin users can access your pages, I think phaselistener is the most elegant solution.


It is so simple that you don’t need to alter all jsp pages to make it check user’s login status.

It goes like this:

1. Create a class that implements the PhaseListener (sample code below)

package tr.oracle.consulting.oidss.utils;

import javax.faces.application.NavigationHandler;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import tr.oracle.consulting.oidss.LoginBean;

public class LoggedInCheck implements PhaseListener {

    public PhaseId getPhaseId() {
        return PhaseId.RESTORE_VIEW;

    }

    public void beforePhase(PhaseEvent event) {
    }

    public void afterPhase(PhaseEvent event) {
        FacesContext fc = event.getFacesContext();

        boolean loginPage = fc.getViewRoot().getViewId().lastIndexOf("login") > -1 ? true : false;
        if (!loginPage && !loggedIn()) {
            NavigationHandler nh = fc.getApplication().getNavigationHandler();
            nh.handleNavigation(fc, null, "logout");
        }
    }

    private boolean loggedIn() {
        return LoginBean.isLoggedIn();

    }
}




2. Next, we register this class as the phase listener of our jsf application. This means, for every request sent to backbone, this class will be called.

Note that there must be isLoogedIn control that checks if we added the user information to session. I added to my LoginBean.

public static boolean isLoggedIn() {
    HttpSession session = (HttpSession)FacesContext.getCurrentInstance().getExternalContext().getSession(true);
    String isLog = (String)session.getAttribute("isLoggedIn");
    System.out.println("isLoggedIn: " + isLog);
    return (isLog != null && isLog.equals("yes"));
}


3. We are setting this session variable in oır LoginBean after checking the the user credentials.
Add this to your faces-config.xml file.



<lifecycle>
   <phase-listener>tr.oracle.consulting.oidss.utils.LoggedInCheck</phase-listener>
</lifecycle>



4. Note that in afterPhase method of our PhaseListener, we use the navigation handler where a “logout” response is handled. To do this, we need a navigation rule inside face-config.xml.



<navigation-rule>
            <from-view-id>/*</from-view-id>
            <navigation-case>
                  <from-outcome>logout</from-outcome>
                  <to-view-id>/pages/login.jsp</to-view-id>
                  <redirect/>
            </navigation-case>
</navigation-rule>



This means redirect to login.jsp page when you recieve “logout” (which is produced by our PhaseListener) regardless of which page you currently are in. (hence from-view-id is *)

3 yorum:

Mohd Haikal Mohd Nashuha dedi ki...
Bu yorum yazar tarafından silindi.
Mohd Haikal Mohd Nashuha dedi ki...

Hey, just stopped by to say that this article helped me alot. I have referenced it in stackoverflow dot com so that others could use the guide as well.

code4fun dedi ki...

Just wanted to thank you. The post helped me a lot.

I have a question: The static method isLoggedIn() always prints null for isLog. Can you please explain what could be the issue.