【问题标题】:How to configure Spring Security to send 'X-CSRF-TOKEN'?如何配置 Spring Security 以发送“X-CSRF-TOKEN”?
【发布时间】:2015-02-11 23:29:22
【问题描述】:

问题是让 CSRF 令牌在 Spring Security 和 Angular 之间工作。

Spring Security CSRF Token Interceptor for Angular 看起来应该可以完成这项工作,但来自服务器的 HEAD 响应中没有“X-CSRF-TOKEN”。

我目前的微型实现在GitHub(标记v.1.0)中可用,如果知道该主题的人能够快速查看代码,我将不胜感激,问题应该很容易发现。

根据文档,我的印象是应该自动启用 CSRF,但似乎并非如此。

如果需要进行不同的配置,我正在使用 Spring Boot,并且更喜欢基于注释的配置而不是 XML。

还有其他方法可以让 Spring Security 对抗 Angular 吗?

【问题讨论】:

  • 您看过即将发布的 4.0 版本了吗?默认情况下启用 CSRF 保护。
  • 我使用的是 3.2,默认情况下它也有 CSRF。但是,我刚刚注意到拦截器有一个已关闭的问题,它用代码示例解释了如何将 CSRF 设置为标头。现在需要学习...

标签: angularjs spring spring-security spring-boot csrf


【解决方案1】:

我相信Angular会寻找一个名为“XSRF-TOKEN”的cookie,所以对客户端来说最简单的事情就是发送它。例如,您可以在Filter 中执行此操作(例如来自https://github.com/spring-guides/tut-spring-security-and-angular-js/blob/master/single/src/main/java/demo/UiApplication.java#L65):

    private Filter csrfHeaderFilter() {
        return new OncePerRequestFilter() {
            @Override
            protected void doFilterInternal(HttpServletRequest request,
                    HttpServletResponse response, FilterChain filterChain)
                    throws ServletException, IOException {
                CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class
                        .getName());
                if (csrf != null) {
                    Cookie cookie = new Cookie("XSRF-TOKEN", csrf.getToken());
                    cookie.setPath("/");
                    response.addCookie(cookie);
                }
                filterChain.doFilter(request, response);
            }
        };
    }

更新:从 spring security 4.2 开始,如果您使用 cookie csrf 存储库(链接仍然是最佳来源),则默认使用正确的 angular cookie 名称,即不再需要自定义过滤器。示例:

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                ...
                .and()
            .csrf()
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());

【讨论】:

  • 我很难理解这如何保护您免受 CSRF 攻击?机制应该相反,你总是设置一个 cookie 值,当它返回时,你应该验证 angular 是否设置了与传入 HTTP 请求的 Header 相同的值。
  • 是的,但是 Spring Security 为您做了这些(您是否点击了链接?)。这只是 Spring 中现有 CRSF 过滤器到角度约定的适配器。它有效,相信我。
  • 这取决于您需要客户端还是服务器端解决方案。
  • 这是我目前最喜欢的解决方案,因为我遇到了拦截器问题。然而,这个解决方案似乎没有问题(并且很容易采用)。
【解决方案2】:

我自己回答这个问题,因为原始 GitHub 存储库中有一个隐藏的问题:Issue #1

解决方案是添加几行 Java 代码,将 CSRF 参数添加为 Http 消息头。

我在 GitHub repo 添加了一个工作解决方案,标签为 v.2.0

【讨论】:

  • 对我来说毕竟不是一个可行的解决方案,因为我在添加此模块后开始收到“跨源请求被阻止”错误消息(使用 Google 地理编码)。已报告问题。
猜你喜欢
  • 2018-02-12
  • 2018-06-06
  • 2017-01-07
  • 2015-03-05
  • 2020-03-25
  • 2018-05-08
  • 2016-05-05
相关资源
最近更新 更多