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:您应该能够添加一个 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 错误页面状态码的主要内容,如果未能解决你的问题,请参考以下文章