Spring安全性中每个请求的CSRF令牌

时间:2017-02-10 18:57:12

标签: spring spring-security csrf csrf-protection

如何在spring security 3.2中为每个请求实现csrf。目前它是按会话处理的。这是必须的要求

请发布需要执行的更改。

> securitycontext.xml

  <http>
    <csrf />
    </http>
给出

并且应用程序正在使用每个会话的令牌

2 个答案:

答案 0 :(得分:1)

您可以通过提供自己的此接口实现来更改CsrfTokenRepository的默认实现,并将其配置为:

...

gulp.task('scripts:watch', () => {
  return gulp.watch([config.filters.app, config.filters.appModuleFiles], ['inject-js']);
})


gulp.task('sass:watch', () => {
  return gulp.watch(config.filters.client, ['inject-sass']);
})

gulp.task('default', ['inject-js', 'inject-bower', 'inject-css', 'scripts:watch', 'sass:watch']);

但是......虽然您写道这是必须要求的,但您应该再次重新考虑它。我甚至建议尝试说服另一端,这种变化可以为应用程序用户带来更多安全性,但也会带来很多不便,有时会出现奇怪的行为,并且通常会降低可用性和用户体验。例如。见Different csrf token per request in Spring security

答案 1 :(得分:0)

我已经实现了一个自定义的csrf令牌存储库,该存储库为每个http POST / DELETE请求生成一个新的令牌。我不认为应该为http GET更新令牌,并且如果您查看spring CsrfFilter类的源代码,它具有一个内部类DefaultRequiresCsrfFilter,该类通过了GET方法的令牌检查。

自定义csrf令牌存储库需要实现接口CsrfTokenRepository。实际上,我已经重用了HttpSessionCsrfTokenRepository的大部分代码,这是Spring的默认设置。需要自定义实现的函数是loadToken()

/*Customized loading token function, which invalidate the CSRF token once it is consumed. A new token is generated on next http req.*/

    public CsrfToken loadToken(HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        CsrfToken token = session == null ? null : (CsrfToken)session.getAttribute(this.sessionAttributeName);
        if (/*HERE http request can be checked to see if it is a POST/DELETE */) {
            if (session != null) {
                //Remove the old token from session, and new token will be generated for next req 
                session.removeAttribute(DEFAULT_CSRF_TOKEN_ATTR_NAME);
            }
        }
        return token;
    }

要加载自定义的csrf令牌存储库,需要在security.xml中对其进行配置,如上面的答案所述。