spring security 3.2.0 csrf 令牌在 freemarker 模板中不起作用

Posted

技术标签:

【中文标题】spring security 3.2.0 csrf 令牌在 freemarker 模板中不起作用【英文标题】:spring security 3.2.0 csrf token not working in freemarker template 【发布时间】:2014-03-12 12:10:40 【问题描述】:

升级到 Spring Security 3.2.0 并配置 xml 后,_csrf 令牌不起作用。

基础知识:

春季 4.0.1 Spring 安全 3.2.0。 Freemarker 模板语言

第 1 步 - spring security xml 配置:

<!-- enable csrf protection via csrf-element -->
<sec:http>
    <!-- -->
    <sec:csrf token-repository-ref="csrfTokenRepository" />
</sec:http>

<!-- rewrite headerName -->
<bean id="csrfTokenRepository" class="org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository">
    <property name="headerName" value="X-SECURITY" />
</bean>

第 2 步 - freemarker 模板:

<form accept-charset="UTF-8" action="/portal" method="POST" name="formAddItemToCart">
    <!-- ... -->

    <!-- inlcude csrf token -->
    <input type="hidden"
           name="$_csrf.parameterName"
           value="$_csrf.token"/>
</form>

第 3 步 - 渲染输出:

<form accept-charset="UTF-8" action="/portal" method="POST" name="formAddItemToCart">
    <!-- ... -->

    <input type="hidden" name="" value=""/>
</form>

第 4 步 - freemarker 模板错误:

FreeMarker template error:
The following has evaluated to null or missing:
==> _csrf  [in template "cart.ftl" at line 28, column 21]

参考: http://docs.spring.io/spring-security/site/docs/3.2.0.RELEASE/reference/htmlsingle/#csrf

目前我正在调试整个应用程序。

我不知道问题到底出在哪里 - 但似乎 csrf 不适用于 freemarker。这通常可以在 freemarker 模板中包含 csrf 令牌吗?您有什么建议或解决方案吗?

【问题讨论】:

Spring Security 的 CSRF 应该可以与 Freemarker 一起正常工作,只要将 CSRF 令牌添加到模型中(这应该默认完成,因为它被设置为 HttpServletRequest 属性)。您是否将 Freemarker 与 Spring MVC(即 FreeMarkerViewResolver)一起使用?您是否配置了任何 块来禁用安全性(即 security=none)?如果是这样,这意味着 CSRF 令牌不会在这些请求中填充,您应该使用 permitAll。 我在 Spring MVC 中使用 Freemarker,并且已经将访问属性配置为 permitAll。但 CSRF 令牌并未在这些请求中填充。 它正在工作 - 更新问题... 非常好......很高兴你能成功:) @m3tr4s 你能把你的更新移到答案部分吗? 【参考方案1】:

更新:

xml 配置不正确。 我发现这个解决方案对我有很大帮助。 https://github.com/spring-projects/spring-mvc-showcase/commit/361adc124c05a8187b84f25e8a57550bb7d9f8e4

现在我的文件如下所示:

安全性.xml

    <sec:http>
        <!-- ... -->
        <sec:csrf />
</sec:http>

<bean id="requestDataValueProcessor" class="org.springframework.security.web.servlet.support.csrf.CsrfRequestDataValueProcessor"/>

<bean id="csrfFilter" class="org.springframework.security.web.csrf.CsrfFilter">
    <constructor-arg>
        <bean class="org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository">
            <property name="headerName" value="X-SECURITY" />
        </bean>
    </constructor-arg>
</bean>

web.xml

 <filter>
    <filter-name>csrfFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <async-supported>true</async-supported>
</filter>

<filter-mapping>
    <filter-name>csrfFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

【讨论】:

以上是关于spring security 3.2.0 csrf 令牌在 freemarker 模板中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

spring security 3.2.0 csrf 令牌在 freemarker 模板中不起作用

在使用 Spring Security 3.2.0 保护应用程序并提供 javascript 文件时,如何设置内容类型标头?

使用 Spring Security 3.2.0.RELEASE,如何在没有标签库的纯 HTML 页面中获取 CSRF 令牌

Spring security 3.2.0 RC1 csrf with multipart/form-data

Maven:Spring 4 + Spring Security

Spring Security 应用程序中的 Sitemesh 未装饰自定义错误页面