Is it possible to configure CSRF protection in grails3 app using spring-security plugin, I can't find anything except useToken attribute for grails form and then call withForm inside controller. But this is actually not a very flexible solution. I like approach with filter like here
For csrf protection I reused org.springframework.security.web.csrf.CsrfFilter. You need to define new bean in grails resouces.groovy (See snipet below - csrfFilter bean). You can define your own accessDeniedHandler and requireCsrfProtectionMatcher. Here is the snippet from resources.groovy:
csrfFilter(CsrfFilter, new HttpSessionCsrfTokenRepository()) {
accessDeniedHandler = ref('fnAccessDeniedHandler')
requireCsrfProtectionMatcher = ref('fnRequireCsrfProtectionMatcher')
}
Now in Bootstrap.groovy add this filter into filter chain:
SpringSecurityUtils.clientRegisterFilter('csrfFilter', SecurityFilterPosition.LAST.order + 10)
Now in your main layout GSP add following tags to add csrf token on each page:
<meta name="_csrf" content="${_csrf?.token}"/>
<!-- default header name is X-CSRF-TOKEN -->
<meta name="_csrf_header" content="${_csrf?.headerName}"/>
So now csrf token presented on each page of your app, you can use it for each ajax request for example (snippet from application.js (I'm using grails 3)):
$(function () {
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
$(document).ajaxSend(function(e, xhr, options) {
xhr.setRequestHeader(header, token);
});
});
For each jquery ajax request we are sending csrf token now.
You can implement it with <g:form> tag:
Example:
<g:form useToken="true" uri="/logout">
Documentation: http://grails.github.io/grails-doc/latest/guide/single.html#formtokens
In my case, I'm using Spring code, so, additionally, I should add manually a _csrf hidden field in the form.
<g:form useToken="true" uri="/logout">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
<input type="submit">Logout</input>
</g:form>
Result:
<form action="/nacho/logout" method="post" >
<!-- this two lines are added automatically by Grails -->
<input type="hidden" name="SYNCHRONIZER_TOKEN" value="883a1037-a2c9-4997-8254-e59da6303494" id="SYNCHRONIZER_TOKEN" />
<input type="hidden" name="SYNCHRONIZER_URI" value="/nacho/userInfo" id="SYNCHRONIZER_URI" />
<!-- this line was added by myself, but, using the ${_csrf} variable -->
<input type="hidden" name="_csrf" value="0928f13c-02aa-4122-8ebe-a1239855a85b"/>
<input type="submit">Logout</input>
</form>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With