在 <protected-views> 中声明的视图在操作 CSRF 令牌后仍然可以访问
View declared in <protected-views> still accessible after manipulating CSRF token
我正在探索 JSF 2.2 中的新功能(到目前为止非常酷)但我仍然不明白受保护视图的工作原理,我创建了一个带有 link 到 facelet2 的 facelet1,如下所示:
<h:link styleClass="link" value="Go to protected page" id="link1"
outcome="/protected/facelet2.xhtml"></h:link>
在我的脸上-config.xml我添加了这个:
<protected-views>
<url-pattern>/protected/facelet2.xhtml</url-pattern>
</protected-views>
现在,当我 运行 页面中添加了一个标记 url:
http://localhost:8080/<project>/protected/facelet2.faces?javax.faces.Token=1426608965211
根据文档,如果令牌与服务器中的令牌不匹配,则不会处理 GET 请求(我的理解是否正确?)。
但是,如果我修改令牌(使用 Firebug 或浏览器中包含的开发工具),即使令牌已修改,请求仍会得到处理。
我是不是做错了什么?
这是因为您的 FacesServlet
显然映射到 *.faces
的 JSF 1.0 样式 URL 模式而不是 [= 的 JSF 2.0 样式 URL 模式15=]。 <protected-views><url-pattern>
必须与您在浏览器地址栏中看到的实际 URL 模式匹配。
因此,给定 /protected/facelet2.faces
的实际 URL,您需要按如下方式配置它:
<protected-views>
<url-pattern>/protected/facelet2.faces</url-pattern>
</protected-views>
但是,我在当前的 Mojarra 2.2.10 实现中发现了一些讨厌的问题:
它实际上并没有根据 Servlet 12.1 规范进行 prefix/suffix 匹配 (there's even a vague comment in source code indicating that!)。它只是精确匹配。这意味着,您不能使用通配符 URL 模式,例如 /protected/*
.
生成 <h:link>
时,它不会将受保护的视图 URL 模式与已解析的 URL 模式进行比较,而是将其与 JSF 视图 ID 进行比较。而且,在检查传入请求时,它不会将请求 URL 与 JSF 视图 ID 进行比较(就像在 link 生成期间一样),而是与 <url-pattern>
进行比较。因此,这永远不会匹配,完全解释了为什么您可以在没有有效令牌的情况下简单地访问它。
基本上,如果您需要保持 *.faces
.
的 JSF 1.0 样式 URL 模式,则需要以下配置
<protected-views>
<url-pattern>/protected/facelet2.xhtml</url-pattern>
<url-pattern>/protected/facelet2.faces</url-pattern>
</protected-views>
在没有有效令牌的情况下访问时,它会正确地抛出 javax.faces.application.ProtectedViewException
。更好的方法是将 FacesServlet
显式映射到 web.xml
中的 *.xhtml
。
<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
这样你就永远不需要处理虚拟 URLs。
我已将此事报告给 Mojarra 的 issue 3837。
另请参阅:
- Sometimes I see JSF URL is *.jsf, sometimes *.xhtml and sometimes /faces/*. Why?
我正在探索 JSF 2.2 中的新功能(到目前为止非常酷)但我仍然不明白受保护视图的工作原理,我创建了一个带有 link 到 facelet2 的 facelet1,如下所示:
<h:link styleClass="link" value="Go to protected page" id="link1"
outcome="/protected/facelet2.xhtml"></h:link>
在我的脸上-config.xml我添加了这个:
<protected-views>
<url-pattern>/protected/facelet2.xhtml</url-pattern>
</protected-views>
现在,当我 运行 页面中添加了一个标记 url:
http://localhost:8080/<project>/protected/facelet2.faces?javax.faces.Token=1426608965211
根据文档,如果令牌与服务器中的令牌不匹配,则不会处理 GET 请求(我的理解是否正确?)。
但是,如果我修改令牌(使用 Firebug 或浏览器中包含的开发工具),即使令牌已修改,请求仍会得到处理。
我是不是做错了什么?
这是因为您的 FacesServlet
显然映射到 *.faces
的 JSF 1.0 样式 URL 模式而不是 [= 的 JSF 2.0 样式 URL 模式15=]。 <protected-views><url-pattern>
必须与您在浏览器地址栏中看到的实际 URL 模式匹配。
因此,给定 /protected/facelet2.faces
的实际 URL,您需要按如下方式配置它:
<protected-views>
<url-pattern>/protected/facelet2.faces</url-pattern>
</protected-views>
但是,我在当前的 Mojarra 2.2.10 实现中发现了一些讨厌的问题:
它实际上并没有根据 Servlet 12.1 规范进行 prefix/suffix 匹配 (there's even a vague comment in source code indicating that!)。它只是精确匹配。这意味着,您不能使用通配符 URL 模式,例如
/protected/*
.生成
<h:link>
时,它不会将受保护的视图 URL 模式与已解析的 URL 模式进行比较,而是将其与 JSF 视图 ID 进行比较。而且,在检查传入请求时,它不会将请求 URL 与 JSF 视图 ID 进行比较(就像在 link 生成期间一样),而是与<url-pattern>
进行比较。因此,这永远不会匹配,完全解释了为什么您可以在没有有效令牌的情况下简单地访问它。
基本上,如果您需要保持 *.faces
.
<protected-views>
<url-pattern>/protected/facelet2.xhtml</url-pattern>
<url-pattern>/protected/facelet2.faces</url-pattern>
</protected-views>
在没有有效令牌的情况下访问时,它会正确地抛出 javax.faces.application.ProtectedViewException
。更好的方法是将 FacesServlet
显式映射到 web.xml
中的 *.xhtml
。
<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
这样你就永远不需要处理虚拟 URLs。
我已将此事报告给 Mojarra 的 issue 3837。
另请参阅:
- Sometimes I see JSF URL is *.jsf, sometimes *.xhtml and sometimes /faces/*. Why?