【问题标题】:JSF 2.0 web.xml error page status codeJSF 2.0 web.xml 错误页面状态码
【发布时间】: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 谢谢我会试一试。

标签: java tomcat jsf-2 web.xml


【解决方案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。

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

    filter>

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

    /filter>

  2. 在你的过滤器类的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 但只显示一个空白页面而不是自定义错误页面。你还有什么想法吗??
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-08
  • 2012-07-30
  • 2015-03-17
  • 1970-01-01
  • 1970-01-01
  • 2013-12-14
  • 1970-01-01
相关资源
最近更新 更多