Integration with RequestDataValueProcessor

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Integration with RequestDataValueProcessor

gihrig
Hello,

I'm working on implementing CSRF protection with:

Thymeleaf 2.1.3.RELEASE
Spring Security 3.2.4.RELEASE
Spring Web MVC 3.2.9.RELEASE

Thymeleaf Spring3 docs http://www.thymeleaf.org/doc/pdf/Thymeleaf-Spring3.pdf
12.1 Integration with RequestDataValueProcessor

Contains this:

th:value calls RequestDataValueProcessor.processFormFieldValue(...) for rendering the value it refers to…

I don't understand what value th:value must refer to, which I interpret to mean the expression th:value 'expands'.

In my Thymeleaf template I have:
<input id="_csrf" name="_csrf" type="hidden" value="" th:value="${_csrf}"/>
In my webmvc-config.xml I have:
<bean name="requestDataValueProcessor"
    class="org.springframework.security.web.servlet.support.csrf.CsrfRequestDataValueProcessor"/>
In my ApplicationContext-security.xml I have:
<http auto-config="true" use-expressions="true" disable-url-rewriting="true">
    
    <!-- Enable Spring Security CSRF feature -->
    <csrf />
    etc…
If I pass in a specific value in the Spring Controller that renders this template, I get that value unaltered in the _csrf field.

If I remove the expression, e.g.
th:value=""
 or
th:value="${}"
 I get an error parsing the template
org.thymeleaf.exceptions.TemplateProcessingException: Could not parse as expression: "${}" (login:64)
If I remove the entry from the controller, but leave the value in the template so there is no value available when the template is rendered I get this in the _csrf field:
value="SaveOnAccessCsrfToken [delegate=org.springframework.security.web.csrf.DefaultCsrfToken@4a4a4296]"
If I use an arbitrary value e.g.
th:value="${xxx}"
 I get no error, but no replacement of the value attribute in the rendered form.

Can you tell me a little more about configuring th:value for Integration with RequestDataValueProcessor than is written in the docs?

Any ideas on what needs to be done to make this work as expected (generate UUID style token)?
Reply | Threaded
Open this post in threaded view
|

Re: Integration with RequestDataValueProcessor

gihrig
There is a subtlety in Thymeleaf-Spring that is IMO, not well documented, but is made clear in this SO question http://stackoverflow.com/questions/23669424/cant-create-csrf-token-with-spring-security 
th:action ... detects when this attribute is being applied on a tag, ... 
and in such case calls RequestDataValueProcessor.getExtraHiddenFields(... ) 
and adds the returned hidden fields just before the closing tag.
In short, this means that you must let Thymeleaf create the form as though it was to be submitted as a 'normal' HTML form, using th:action -- Even though it will ultimately be be submitted by a Javascript AJAX call, or other means beyond html submit. In this case the value generated by Thymeleaf's 'th:action' tag is never used, but the mere use of th:action enables the token generation.

Additionally, the 'value' for th:action can apparently, be any parse-able expression. The value for th:value is a mute point, as the entire <input ... /> tag is inserted 'automagically' by Thymeleaf.

Given the apparent need for th:action and the automatic insertion of the <input /> tag, I wonder at the applicability of th:href, the:src, th:value or th:field in this CSRF context. I'm sure I'm missing many important points, but this required a full day of 'research' to get the _csrf token inserted into the form.

The fact that the SO question was answered by the OP (Original Poster) some 2 weeks later, suggests that there are few who actually know how this stuff works. I'm a bit surprised at that.

Please update section 12.1 "Integration with RequestDataValueProcessor" of the Thymeleaf Spring 3 docs accordingly.
Reply | Threaded
Open this post in threaded view
|

Re: Integration with RequestDataValueProcessor

sunil0791