I need to allow only logged-in users to most of the pages of my application. I am developing a Java Enterprise application with JSF 2. Does anyone know how I can do that? maybe
There are many ways to achieve that. The easiest and probably the most popular way would be to use servlet filter, you can find more information about such a mechanism here: Basic Security in JSF
There are different ways to do that . Firstly you can use filters to control page access or you can use phase listeners that listens jsf phases .
I wanna give you two examples for them ;
public class SecurityFilter implements Filter{
FilterConfig fc;
public void init(FilterConfig filterConfig)throws ServletException {
fc = filterConfig;
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException{
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse resp = (HttpServletResponse) response;
HttpSession session = req.getSession(true);
String pageRequested = req.getRequestURI().toString();
if(session.getAttribute("user") == null && !pageRequested.contains("login.xhtml")){
resp.sendRedirect("login.xhtml");
}else{
chain.doFilter(request, response);
}
}
public void destroy(){
}
}
And you should add this filter to web.xml;
<filter>
<filter-name>SecurityFilter</filter-name>
<filter-class>com.webapp.SecurityFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SecurityFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Phase Listener example ;
public class SecurityFilter implements PhaseListener {
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 && !isUserLogged()) {
navigate(event,"logout");
}
}
private boolean isUserLogged() {
//looks session for user
}
private void navigate(PhaseEvent event, String page) {
FacesContext fc = event.getFacesContext();
NavigationHandler nh = fc.getApplication().getNavigationHandler();
nh.handleNavigation(fc, null, page);
}
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}
}
So if you want to use listener you should add this to your faces-config.xml ; Note : "logout" is a navigation rule which is defined in faces-config
<lifecycle>
<phase-listener>com.myapp.SecurityFilter</phase>
</lifecycle>
Edit : The navigation rule ;
<navigation-rule>
<from-view-id>/*</from-view-id>
<navigation-case>
<from-outcome>logout</from-outcome>
<to-view-id>/login.xhtml</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
You can put your user to session in login method like that ;
FacesContext context = FacesContext.getCurrentInstance();
HttpSession session =
(HttpSession)context.getExternalContext().getSession(true);
session.setAttribute("user", loggedUser);