Проблема с использованием аутентификации HttpServletRequest() в прослушивателе JSF 2.0 preRenderView

Я пытаюсь использовать аутентификацию() в методе прослушивателя preRenderView, чтобы условно инициировать аутентификацию в зависимости от параметров просмотра на странице. Я попытался добавить простой метод:

@Named
@RequestScoped
public class PermissionBean implements java.io.Serializable {
public void preRender() {
System.out.println("IN PRERENDER");

HttpServletRequest request = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
HttpServletResponse response = (HttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
try {
    request.authenticate(response);
} catch (Exception e) { // may throw ServletException or IOException
    e.printStackTrace();
}

}

Сам метод аутентификации не генерирует исключение, он запускает перенаправление на Login.xhtml, как и ожидалось. Тем не менее, я получаю в своем журнале сервера, я получаю это исключение:

enter code here

INFO: IN PRERENDER
FINEST: GET /Login.xhtml previous[3]
INFO: 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)
at javax.faces.component.UIComponent$ComponentSystemEventListenerAdapter.processEvent(UIComponent.java:2508)
at javax.faces.event.SystemEvent.processListener(SystemEvent.java:106)
at com.sun.faces.application.ApplicationImpl.processListeners(ApplicationImpl.java:2129)
at com.sun.faces.application.ApplicationImpl.invokeComponentListenersFor(ApplicationImpl.java:2077)
at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:286)
at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:244)
at javax.faces.application.ApplicationWrapper.publishEvent(ApplicationWrapper.java:670)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:108)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)

Так что мой запрос не перенаправляется на Login.xhtml.

Мой вопрос: это то, что должно работать в управляемом компоненте JSF, или это разрешено только вне жизненного цикла запроса JSF? Я попытался вызвать authentication() из WebFilter, и он работает, как и ожидалось.

Спасибо, Эллен


person Ellen    schedule 10.08.2011    source источник


Ответы (1)


Вам нужно сообщить JSF, чтобы он не отображал ответ, который его изначально просили сделать, всякий раз, когда запрос был перенаправлен. Вы можете сделать это, проверив HttpServletRequest#authenticate() возвращает false, а затем вызывает FacesContext#responseComplete() соответственно.

if (!request.authenticate(response)) {
    FacesContext.getCurrentInstance().responseComplete();
}
person BalusC    schedule 10.08.2011
comment
Мне неловко говорить, что я не проверил это правильно - я просто понял, что забыл удалить созданный мной ServletFilter, поэтому аутентифицировался ServletFilter, а не мой метод прослушивателя. Когда я удалил ServletFilter, вызов responseComplete() завершился неудачно, потому что текущий FacesContext имеет значение null после вызова аутентификации. Я не уверен в протоколе для этого - должен ли я открыть новый вопрос? - person Ellen; 12.08.2011