JSF 2.0 web.xml 错误页面状态码

Posted

技术标签:

【中文标题】JSF 2.0 web.xml 错误页面状态码【英文标题】:JSF 2.0 web.xml error page status code 【发布时间】:2013-12-18 22:14:40 【问题描述】:

我目前正在修改使用 JSF 创建的应用程序。有关我正在做的事情的一些背景信息,请阅读下文。

背景

Acunetix 扫描在处理 javax.faces.ViewState 的值时,在我的大多数页面中检测到一个称为“应用程序错误消息”的中等安全问题。 Acunetix 扫描将视图状态更改为随机值或空字符串,这会导致我的应用程序引发异常。使用 web.xml 文件中的以下配置的自定义错误页面会捕获异常。

<error-page>
  <error-code>500</error-code>
  <location>/unhandled.xhtml</location>
</error-page>

<error-page>
  <exception-type>java.lang.Throwable</exception-type>
  <location>/unhandled.xhtml</location>
</error-page>

这按预期工作,并显示自定义错误页面。但是,Acunetix 扫描将此视为漏洞,因为它在标头中看到 500 状态代码以及错误消息 Internal Server Error。

Acunetix 扫描摘录

/webapp/login.xhtml
Details
URL encoded Post input javax.faces.ViewState was set to
Error message found: Internal Server Error

问题:

是否可以将错误页面的状态代码更改为 200 而不是 500。如果不能,任何人都可以建议一种解决方法,让我可以操纵页面状态代码。

注意:

请注意,我使用以下框架 Spring、JSF 2.0、Primefaces 3.4、Hibernate、Omnifaces(FacesEceptionFilter & FullAjaxExceptionHandlerFactory)、Tomcat 7 服务器。

感谢您的帮助...

【问题讨论】:

我不这么认为,但最明显的问题是你试过了吗?也就是web.xml中的200改成500了吗?如果有,是否达到了预期的效果? @EJK 感谢您的评论,但我真正想要的(作为解决方法)是错误页面的响应标头为 200,因为它目前为 500。 @EJK 不管怎样,我将错误代码替换为 200 并删除了 java.lang.Throwable 异常类型,因此我可以尝试您的建议。我只是被重定向到默认的 404 而不是我的自定义错误页面,因为错误代码不匹配。 在下面查看我的答案。我认为 servlet 过滤器就是答案。 @EJK 谢谢我会试一试。 【参考方案1】:

我通过这样做解决了我的问题。在我的错误页面中,我刚刚添加了一个事件监听器,将状态码强制为 200。

<?xml version="1.0" encoding="ISO-8859-1" ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/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:p="http://primefaces.org/ui">

       <f:view contentType="text/html">
          <f:metadata>
             <f:event type="preRenderView" listener="#errorController.forceStatusCode200()"></f:event>
          </f:metadata>

          <h:body>
             <h1>ZZZZZZZZZ</h1>
          </h:body>
       </f:view>
    </html>

在我的 managedBean 中

@component("errorController")
@Scope("view")
public class ErrorController

   public void forceStatusCode200()
   
      FacesContext fc = FacesContext.getCurrentInstance();
      ExternalContext ec = fc.getExternalContext();
      HttpServletResponse hp = (HttpServletResponse) ec.getResponse();
      hp.setStatus(HttpServletResponse.SC_OK);
   

当我使用 Fiddler 检查响应的状态代码时这样做,我再也看不到错误代码 500。

我希望这对某人有所帮助。另外,如果有人可以指出任何不良副作用,请不要犹豫。

感谢您的宝贵时间...

【讨论】:

我会在几天内不回答这个问题,以防有人有更好的答案。 或者只是ec.setResponseStatus(HttpServletResponse.SC_OK); 没有额外的支持bean:【参考方案2】:

您应该能够添加一个 servlet 过滤器,无条件地将所有响应代码设置为 200。

    在 web.xml 中注册您的过滤器,如下所示:

    filter>

        <filter-name>StatusCodeFilter</filter-name>
    
        <filter-class>com.foo.StatusCodeFilter</filter-class> 
    

    /filter>

    在你的过滤器类的doFilter方法中,设置响应码如下:

       @Override
       public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
           throws IOException, ServletException 
    
               ((HttpServletResponse)response).setStatus(HttpServletResponse.SC_OK);
    

【讨论】:

嗨,不幸的是,刚刚测试了你的想法,它似乎不起作用。因为我还需要调用 chain.doFilter() 方法。如果我在 chain.dofilter() 之前设置状态,则状态代码将被覆盖。我还尝试在捕获 chain.dofilter() 引发的错误后设置状态代码,它仍然被覆盖。如果我重新抛出异常,我假设它在 applicationfilter 或来自 tomcat 的 errorvalve 中被覆盖。如果我不重新抛出异常状态代码设置为 200 但只显示一个空白页面而不是自定义错误页面。你还有什么想法吗??

以上是关于JSF 2.0 web.xml 错误页面状态码的主要内容,如果未能解决你的问题,请参考以下文章

如何在多个战争之间共享一个jsf错误页面

Servlet 异常处理( 配置错误页面)

JSF 2.0 验证码如何工作

JSF 2.0:跨多个视图保留组件状态

JSF 2.0 部分状态保存似乎不起作用

错误页设置,设置HTTP状态码404,500