Grails 3 CSRF保护

Grails 3 CSRF保护,grails,spring-security,csrf,grails-3.0,Grails,Spring Security,Csrf,Grails 3.0,是否可以使用spring安全插件在grails3应用程序中配置CSRF保护,除了grails表单的useToken属性,我找不到任何东西,然后在控制器内部调用withForm。但这实际上不是一个非常灵活的解决方案。我喜欢使用类似过滤器的方法,您可以使用标签来实现: 示例: <g:form useToken="true" uri="/logout"> <form action="/nacho/logout" method="post" > <!-- thi

是否可以使用spring安全插件在grails3应用程序中配置CSRF保护,除了grails表单的useToken属性,我找不到任何东西,然后在控制器内部调用withForm。但这实际上不是一个非常灵活的解决方案。我喜欢使用类似过滤器的方法,您可以使用标签来实现:

示例:

<g:form useToken="true" uri="/logout">
<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>

文档:

在我的例子中,我使用的是Spring代码,因此,另外,我应该在表单中手动添加一个_csrf隐藏字段

<g:form useToken="true" uri="/logout">
    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
    <input type="submit">Logout</input>
</g:form>

注销
结果:

<g:form useToken="true" uri="/logout">
<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>

注销

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

csrfFilter(CsrfFilter, new HttpSessionCsrfTokenRepository()) {
    accessDeniedHandler = ref('fnAccessDeniedHandler')
    requireCsrfProtectionMatcher = ref('fnRequireCsrfProtectionMatcher')
}
现在在Bootstrap.groovy中,将此过滤器添加到过滤器链中:

 SpringSecurityUtils.clientRegisterFilter('csrfFilter',    SecurityFilterPosition.LAST.order + 10)
现在,在您的主布局中,GSP添加以下标记以在每个页面上添加csrf令牌:

<meta name="_csrf" content="${_csrf?.token}"/>
<!-- default header name is X-CSRF-TOKEN -->
<meta name="_csrf_header" content="${_csrf?.headerName}"/>

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

是的,但是在后端,您应该始终使用withForm方法,这是一个丑陋的解决方案。最好的选择是使用spring security的CrsfFilter,我成功地设置了它,现在它工作正常,但感谢您的回复:)@enzo您能分享您的配置吗?也许通过提交它来回答这个问题?非常感谢@EdJ看到我上面的答案,如果你有任何问题,请问我。@enzo一个问题朋友:我的项目中有多重形式。我是否应该在main.gsp中添加:$(函数(){var token=$(“meta[name=''u csrf']”)attr(“content”);var header=$(“meta[name='u csrf']”)attr(“content”);$(document).ajaxSend(函数(e,xhr,选项){xhr.setRequestHeader(header,token);});您是否介意分享一个自定义accessDeniedHandler和requireCsrfProtectionMatcher类的示例?旧线程,但如果有帮助,请参阅: