I'm currently using a PhaseListener
as below to perform user authorization.
private PhaseId phaseId = PhaseId.RESTORE_VIEW;
@Override
public void afterPhase(PhaseEvent event) {
FacesContext fc = event.getFacesContext();
boolean isOnAllowedPage = false;
String[] allowedPages = choseRightPages(); // chose pages for role
for (String s : allowedPages) {
if (fc.getViewRoot().getViewId().lastIndexOf(s) > -1) {
isOnAllowedPage = true;
break;
}
}
if (!isOnAllowedPage) {
NavigationHandler nh = fc.getApplication().getNavigationHandler();
nh.handleNavigation(fc, null, "prohibited");
}
}
It does what I want, however I don't see it being listed in How to handle authentication/authorization with users in a database? and this Coderanch topic titled "authorization with phaselistener problem" also mentions the following:
You shouldn't couple authorization that tight with JSF. Better make use of container managed authentication and/or a simple filter acting on an url-pattern covering the protected pages.
I don't exactly understand the limitations of using a PhaseListener
instead of a Filter
when performing user authorization. Can someone explain it to me?
A PhaseListener
is only fired on a JSF request (i.e. a HTTP request which invoked the FacesServlet
). It's not fired when a non-JSF request is executed and thus exposes a potential security leak on non-JSF requests. A servlet Filter
can be fired on every single HTTP request, regardless of the target servlet.
In other words: HTTP request authorization should not be tied to having the FacesContext
available, but to the ServletRequest
available. Always try to authorize as "low level" as possible.
来源:https://stackoverflow.com/questions/29600300/limitations-of-using-a-phaselistener-instead-of-a-servlet-filter-for-authorizati