操作CSRF令牌后仍可访问<protected-views>中声明的视图

CIO*_*IOC 5 jsf facelets jsf-2.2 protected-views

我正在探索JSF 2.2中的新功能(到目前为止非常酷),但我仍然不明白受保护的视图是如何工作的,我创建了一个带有facelet2链接的facelet1,如下所示:

<h:link styleClass="link" value="Go to protected page" id="link1"
    outcome="/protected/facelet2.xhtml"></h:link>
Run Code Online (Sandbox Code Playgroud)

在我的faces-config.xml中我添加了这个:

<protected-views>
    <url-pattern>/protected/facelet2.xhtml</url-pattern>
</protected-views>
Run Code Online (Sandbox Code Playgroud)

现在,当我运行页面时,在URL中添加了一个标记:

http://localhost:8080/<project>/protected/facelet2.faces?javax.faces.Token=1426608965211
Run Code Online (Sandbox Code Playgroud)

根据文档,如果令牌与服务器中的令牌不匹配,则不处理GET请求(我的理解是否正确?).

但是,如果我修改令牌(使用Firebug或浏览器中包含的开发工具),即使令牌已被修改,仍会处理请求.

难道我做错了什么?

Bal*_*usC 5

这是因为你FacesServlet显然是映射在JSF 1.0风格的URL模式*.faces而不是JSF 2.0风格的URL模式*.xhtml.将<protected-views><url-pattern>你在浏览器地址栏中必须看到实际的URL模式相匹配.

因此,给定实际的URL /protected/facelet2.faces,您需要将其配置如下:

<protected-views>
    <url-pattern>/protected/facelet2.faces</url-pattern>
</protected-views>
Run Code Online (Sandbox Code Playgroud)

然而,在此期间,我发现了当前Mojarra 2.2.10实现中的一些令人讨厌的问题:

  1. 它确实没有按照Servlet 12.1规范进行前缀/后缀匹配(在源代码中甚至有一个模糊的注释表明!).它只是一个完全匹配.这意味着,您不能使用通配符URL模式/protected/*.

  2. 生成时<h:link>,它不会将受保护的视图URL模式与已解析的URL进行比较,而是将其与JSF视图ID进行比较.并且,在检查传入请求时,它不会将请求URL与JSF视图ID进行比较(如在链接生成期间),而是与<url-pattern>.因此,这永远不会匹配,完全解释为什么您可以在没有有效令牌的情况下简单地访

基本上,如果需要保留JSF 1.0样式的URL模式,则需要以下配置*.faces.

<protected-views>
    <url-pattern>/protected/facelet2.xhtml</url-pattern>
    <url-pattern>/protected/facelet2.faces</url-pattern>
</protected-views>
Run Code Online (Sandbox Code Playgroud)

然后javax.faces.application.ProtectedViewException 在没有有效令牌的情况下进行访问时正确抛出.更好的是刚刚在地图FacesServlet上显式*.xhtmlweb.xml.

<servlet-mapping>
    <servlet-name>facesServlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
Run Code Online (Sandbox Code Playgroud)

这样您就不需要处理虚拟URL.

我已经向Mojarra家伙报告过这个问题3837.

也可以看看: