grailsspring-securitycsrfgrails-3.0

Grails 3 CSRF protection


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


Solution

  • 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.