Grails 3 CSRF保护

enz*_*nzo 3 grails csrf spring-security csrf-protection grails-3.0

是否可以使用spring-security插件在grails3 app中配置CSRF保护,除了grails表单的useToken属性之外我找不到任何东西,然后在控制器内调用withForm.但这实际上不是一个非常灵活的解决方案.我喜欢像这里一样使用过滤器

enz*_*nzo 10

对于csrf保护,我重用了org.springframework.security.web.csrf.CsrfFilter.您需要在grails resouces.groovy中定义新bean(请参阅下面的snipet - csrfFilter bean).您可以定义自己的accessDeniedHandlerrequireCsrfProtectionMatcher.这是resources.groovy的片段:

csrfFilter(CsrfFilter, new HttpSessionCsrfTokenRepository()) {
    accessDeniedHandler = ref('fnAccessDeniedHandler')
    requireCsrfProtectionMatcher = ref('fnRequireCsrfProtectionMatcher')
}
Run Code Online (Sandbox Code Playgroud)

现在在Bootstrap.groovy中将此过滤器添加到过滤器链中:

 SpringSecurityUtils.clientRegisterFilter('csrfFilter',    SecurityFilterPosition.LAST.order + 10)
Run Code Online (Sandbox Code Playgroud)

现在,在您的主要布局GSP中添加以下标记,以在每个页面上添加csrf标记:

<meta name="_csrf" content="${_csrf?.token}"/>
<!-- default header name is X-CSRF-TOKEN -->
<meta name="_csrf_header" content="${_csrf?.headerName}"/>
Run Code Online (Sandbox Code Playgroud)

所以现在csrf令牌出现在你的应用程序的每个页面上,你可以将它用于每个ajax请求,例如(来自application.js的片段(我使用的是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);
    });
});
Run Code Online (Sandbox Code Playgroud)

对于每个jquery ajax请求,我们现在发送csrf令牌.

  • 您是否介意共享自定义*accessDeniedHandler*和*requireCsrfProtectionMatcher*类的示例? (5认同)