如何将CSRF令牌从AngularJS前端发送到Spring REST服务后端

How do I send CSRF tokens from AngularJS front end to Spring REST service backend?

本文关键字:Spring REST 后端 服务 前端 CSRF 令牌 AngularJS      更新时间:2023-09-26

如何在 AngularJS 前端和 Spring Boot REST 后端之间设置 CSRF 保护? 让我们以下面代码中的http.post("/send-pin", JSONobject)...调用为例。

当我尝试使用 http.post("/send-pin", JSONobject)... 从 AngularJS 前端方法以 /send-pin url 模式调用 Spring Boot REST 服务时,我在服务器日志中收到以下错误:

Invalid CSRF token found for http://localhost:9000/send-pin

我阅读了另一篇帖子,其中指出需要在发出请求的 AngularJS 代码中设置 csrf 令牌,但链接中的代码使用语法$(document).ajaxSend(function(e, xhr, options) {xhr.setRequestHeader('X-CSRF-TOKEN', token);});,它不会直接粘贴到我下面的代码中。 此外,链接中的 clode 从表单中获取数据,而我的代码从 AngularJS 控制器获取数据。 需要对下面的代码进行哪些具体更改,以便后端 REST 服务能够成功处理 AngularJS 应用程序对在 localhost:9000/send-pin url 上运行的 REST 服务发出的请求?

这是 AngularJS 中的方法:

$scope.login = function() {
    auth.authenticate1($scope.credentials, function(authenticated1) {
        if (authenticated1) {//authenticated1 returns true
            var resultmessage = { "name": $scope.credentials.username };
            $http.post('/send-pin', resultmessage).then(function(response) {//this call triggers the Invalid CSRF token error shown above
                $scope.processStep = response.data.content;
                auth.usrname = response.data.name;
            });
            $scope.error = false;
        } else {
            $scope.error = true;
        }
    })
}

下面是设置 SpringSecurity 配置的 UiApplication.java 类:

@SpringBootApplication
@Controller
@EnableJpaRepositories(basePackages = "demo", considerNestedRepositories = true)
public class UiApplication extends WebMvcConfigurerAdapter {
    // Match everything without a suffix (so not a static resource)
    @RequestMapping(value = "/{[path:[^''.]*}")
    public String redirect() {
        // Forward to home page so that route is preserved.
        return "forward:/";
    }
    @RequestMapping("/user")
    @ResponseBody
    public Principal user(HttpSession session, Principal user) {
        return user;
    }
    public static void main(String[] args) {
        SpringApplication.run(UiApplication.class, args);
    }
    @Bean
    public LocaleResolver localeResolver() {
        SessionLocaleResolver slr = new SessionLocaleResolver();
        slr.setDefaultLocale(Locale.US);
        return slr;
    }
    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {
        LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
        lci.setParamName("lang");
        return lci;
    }
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/login").setViewName("login");
    }
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(localeChangeInterceptor());
    }
    @Order(Ordered.HIGHEST_PRECEDENCE)
    @Configuration
    protected static class AuthenticationSecurity extends GlobalAuthenticationConfigurerAdapter {
        @Autowired
        private Users users;
        @Override
        public void init(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(users);
        }
    }
    @SuppressWarnings("deprecation")
    @Configuration
    @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
    @EnableWebMvcSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.httpBasic().and().authorizeRequests()
                .antMatchers("/check-pin").permitAll()
                .antMatchers("/index.html", "/", "/login", "/someotherrurl") 
                .permitAll().anyRequest().authenticated().and().csrf()
                .csrfTokenRepository(csrfTokenRepository()).and()
                .addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
        }
        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 = WebUtils.getCookie(request, "XSRF-TOKEN");
                        String token = csrf.getToken();
                        if (cookie == null || token != null && !token.equals(cookie.getValue())) {
                            cookie = new Cookie("XSRF-TOKEN", token);
                            cookie.setPath("/");
            response.addCookie(cookie);
                        }
                    }
                    filterChain.doFilter(request, response);
                }
            };
        }
        private CsrfTokenRepository csrfTokenRepository() {
            HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
            repository.setHeaderName("X-XSRF-TOKEN");
            return repository;
        }
    }   
}

以下是 Linux 终端的错误日志,在 REST 服务运行时打印出来:

2016-01-15 13:15:27.704 DEBUG 7031 --- [nio-9000-exec-1] tRepository$SaveToSessionResponseWrapper : Skip invoking on
2016-01-15 13:15:27.704 DEBUG 7031 --- [nio-9000-exec-1] tRepository$SaveToSessionResponseWrapper : Skip invoking on
2016-01-15 13:15:27.704 DEBUG 7031 --- [nio-9000-exec-1] o.s.s.w.a.ExceptionTranslationFilter     : Chain processed normally
2016-01-15 13:15:27.704 DEBUG 7031 --- [nio-9000-exec-1] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2016-01-15 13:15:27.713 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/css/**'
2016-01-15 13:15:27.713 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/js/**'
2016-01-15 13:15:27.713 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/images/**'
2016-01-15 13:15:27.713 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/**/favicon.ico'
2016-01-15 13:15:27.713 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/error'
2016-01-15 13:15:27.713 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/autoconfig']
2016-01-15 13:15:27.713 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/autoconfig'
2016-01-15 13:15:27.713 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/autoconfig/**']
2016-01-15 13:15:27.713 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/autoconfig/**'
2016-01-15 13:15:27.713 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/autoconfig.*']
2016-01-15 13:15:27.713 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/autoconfig.*'
2016-01-15 13:15:27.713 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/autoconfig/']
2016-01-15 13:15:27.713 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/autoconfig/'
2016-01-15 13:15:27.713 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/metrics']
2016-01-15 13:15:27.713 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/metrics'
2016-01-15 13:15:27.713 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/metrics/**']
2016-01-15 13:15:27.713 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/metrics/**'
2016-01-15 13:15:27.713 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/metrics.*']
2016-01-15 13:15:27.713 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/metrics.*'
2016-01-15 13:15:27.713 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/metrics/']
2016-01-15 13:15:27.713 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/metrics/'
2016-01-15 13:15:27.713 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/trace']
2016-01-15 13:15:27.713 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/trace'
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/trace/**']
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/trace/**'
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/trace.*']
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/trace.*'
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/trace/']
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/trace/'
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/env']
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/env'
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/env/**']
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/env/**'
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/env.*']
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/env.*'
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/env/']
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/env/'
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/health']
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/health'
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/health/']
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/health/'
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/mappings']
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/mappings'
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/mappings/**']
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/mappings/**'
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/mappings.*']
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/mappings.*'
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/mappings/']
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/mappings/'
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/dump']
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/dump'
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/dump/**']
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/dump/**'
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/dump.*']
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/dump.*'
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/dump/']
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/dump/'
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/error']
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/error'
2016-01-15 13:15:27.714 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/error/']
2016-01-15 13:15:27.715 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/error/'
2016-01-15 13:15:27.715 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/beans']
2016-01-15 13:15:27.716 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/beans'
2016-01-15 13:15:27.716 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/beans/**']
2016-01-15 13:15:27.716 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/beans/**'
2016-01-15 13:15:27.717 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/beans.*']
2016-01-15 13:15:27.717 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/beans.*'
2016-01-15 13:15:27.717 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/beans/']
2016-01-15 13:15:27.717 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/beans/'
2016-01-15 13:15:27.717 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/info']
2016-01-15 13:15:27.717 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/info'
2016-01-15 13:15:27.717 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/info/']
2016-01-15 13:15:27.717 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/info/'
2016-01-15 13:15:27.717 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/configprops']
2016-01-15 13:15:27.717 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/configprops'
2016-01-15 13:15:27.717 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/configprops/**']
2016-01-15 13:15:27.717 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/configprops/**'
2016-01-15 13:15:27.717 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/configprops.*']
2016-01-15 13:15:27.717 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/configprops.*'
2016-01-15 13:15:27.717 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/configprops/']
2016-01-15 13:15:27.717 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/send-pin'; against '/configprops/'
2016-01-15 13:15:27.717 DEBUG 7031 --- [io-9000-exec-10] o.s.s.web.util.matcher.OrRequestMatcher  : No matches found
2016-01-15 13:15:27.717 DEBUG 7031 --- [io-9000-exec-10] o.s.security.web.FilterChainProxy        : /send-pin at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2016-01-15 13:15:27.717 DEBUG 7031 --- [io-9000-exec-10] o.s.security.web.FilterChainProxy        : /send-pin at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2016-01-15 13:15:27.717 DEBUG 7031 --- [io-9000-exec-10] w.c.HttpSessionSecurityContextRepository : Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@d8393cb4: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@d8393cb4: Principal: org.springframework.security.core.userdetails.User@63d9948c: Username: another@shirt.com; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffdaa08: RemoteIpAddress: 127.0.0.1; SessionId: 61483B5DDC3336EC44BF528C97749AA9; Granted Authorities: ROLE_USER'
2016-01-15 13:15:27.717 DEBUG 7031 --- [io-9000-exec-10] o.s.security.web.FilterChainProxy        : /send-pin at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2016-01-15 13:15:27.717 DEBUG 7031 --- [io-9000-exec-10] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@4f81666
2016-01-15 13:15:27.723 DEBUG 7031 --- [io-9000-exec-10] o.s.security.web.FilterChainProxy        : /send-pin at position 4 of 12 in additional filter chain; firing Filter: 'CsrfFilter'
2016-01-15 13:15:27.724 DEBUG 7031 --- [io-9000-exec-10] o.s.security.web.csrf.CsrfFilter         : Invalid CSRF token found for http://localhost:9000/send-pin
2016-01-15 13:15:27.725 DEBUG 7031 --- [io-9000-exec-10] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
$.ajaxSend仅适用于

jQuery $.ajax,而不适用于其他库或框架(如Angular)进行的其他ajax调用。

来自角度$http文档:

XSRF 是一种技术,未经授权的站点可以通过该技术获取用户的私人数据。Angular提供了一种对抗XSRF的机制。执行 XHR 请求时,$http 服务从 cookie(默认情况下为 XSRF-TOKEN)读取令牌,并将其设置为 HTTP 标头(X-XSRF-TOKEN)。

因此,请确保您设置了适当的cookie,angular将在内部处理标题

注意:我是OP,这个答案是实际解决问题的原因。

对此的解决方案需要将以下行添加到 SecurityConfiguration 类中:

.antMatchers("/send-pin").permitAll()  

此更改导致 SecurityConfiguration.configure(...) 方法现在如下所示:

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic().and().authorizeRequests()
            .antMatchers("/send-pin").permitAll() 
            .antMatchers("/check-pin").permitAll()
            .antMatchers("/index.html", "/", "/login", "/someotherrurl") 
            .permitAll().anyRequest().authenticated().and().csrf()
            .csrfTokenRepository(csrfTokenRepository()).and()
            .addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
    }  

请注意 OP 版本的一行变化。 这是一个非常简单的答案。 几乎羞于发布它,因为它是如此明显,但我发布它是为了帮助将来遇到类似问题的其他人。

我在尝试@charlieti的建议检查Firefox调试工具的网络选项卡后发现了这一点,该选项卡显示以下两个cookie是随请求一起发送的:JSESSIONID:"99192501E7CEA0EDEF853BD666AF3C35"XSRF-TOKEN:"b50afb87-e15c-4bef-93ca-7c2fdf145fd8",即使同一请求的服务器日志仍然归结为Invalid CSRF token found for http://localhost:9000/send-pin。 这导致我检查为什么发送的令牌被拒绝,几分钟后我注意到 url 模式缺少antmatchers(...),从而得出了这个答案。