我正在尝试在 JSF 托管 bean 中使用 HttpServletRequest 身份验证来实现细粒度身份验证,具体取决于请求的特定对象。
当我在 preRenderView 事件侦听器中调用身份验证时,如果身份验证导致重定向到登录页面,则会引发异常。我无法在调用进行身份验证后调用 responseComplete,因为 FacesContext.getCurrentInstance 返回 null。是否可以在 JSF 中调用 authenticate(),还是必须使用 ServletFilter?HttpServletRequest 登录和注销在 JSF 中工作,所以我认为假设身份验证应该工作是合理的。这是 Mojarra JSF 中的错误吗?
这是我的代码:
注册事件监听的页面:
<ui:composition template="/template.xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ice="http://www.icesoft.com/icefaces/component">
<ui:param name="pageTitle" value="Text Clustering Home Page"/>
<ui:define name="metadata">
<f:metadata>
<f:event type="preRenderView" listener="#{permissionBean.preRender}"/>
</f:metadata>
</ui:define>
<ui:define name="body">
Text Clustering Home Page
<h:form>
<h:panelGrid columns="1">
<ice:outputText rendered="#{loginService.loggedIn}" value="Logged in User: #{loginService.currentUser.username}"/>
<h:link rendered="#{!loginService.loggedIn}" value="Register" outcome="Register"/>
<h:commandLink value="Logout" rendered="#{loginService.loggedIn}" action="#{loginService.logout}"/>
<h:link value="Login" rendered="#{!loginService.loggedIn}" outcome="Login"/>
</h:panelGrid>
</h:form>
包含监听器的 bean:
@Named
@RequestScoped
public class PermissionBean implements java.io.Serializable {
public void preRender(CompenentSystemEvent event) {
HttpServletRequest request = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
HttpServletResponse response = (HttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
try {
if (!request.authenticate(response)) {
System.out.println("After authenticate, context = " +FacesContext.getCurrentInstance());
if (FacesContext.getCurrentInstance()!=null) {
FacesContext.getCurrentInstance().responseComplete();
}
}
} catch (Exception e) { // may throw ServletException or IOException
System.out.println("EXCEPTION calling authenticate");
e.printStackTrace();
}
}
}
对 authenticate() 的调用不会引发异常,但是如果它返回 false,那么 FacesContext.getCurrentInstance() 也会返回 null,并且在方法退出后我会收到此错误:
javax.enterprise.resource.webcontainer.jsf.context|_ThreadID=23;_Thread
Name=Thread-3;|Exception when handling error trying to reset the
response.
java.lang.NullPointerException
at
com.sun.faces.facelets.tag.jsf.core.DeclarativeSystemEventListener.processEvent(EventHandler.java:126 )
谢谢,艾伦