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

Posted

技术标签:

【中文标题】如何将 CSRF 令牌从 AngularJS 前端发送到 Spring REST 服务后端?【英文标题】:How do I send CSRF tokens from AngularJS front end to Spring REST service backend? 【发布时间】:2016-04-21 14:39:35 【问题描述】:

如何在 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

我读到this other posting,它指出需要在发出请求的AngularJS代码中设置csrf令牌,但链接中的代码使用语法$(document).ajaxSend(function(e, xhr, options) xhr.setRequestHeader('X-CSRF-TOKEN', token););,它不会直接粘贴到我下面的代码中.此外,链接中的代码从表单中获取数据,而我的代码从 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

【问题讨论】:

【参考方案1】:

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

来自angular $http docs:

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

所以请确保您设置了适当的 cookie,并且 Angular 会在内部处理标题

【讨论】:

对不起,我对 spring 一无所知,但查找 csrf cookie 处理应该很容易 在手册中查找应该不难。使用浏览器开发工具查看任何页面上设置的 cookie 也很简单 我在 15 秒内使用 google spring csrf cookie ***.com/questions/31389120/spring-csrf-angularjs 找到了这个 使用浏览器开发工具网络检查实际请求。可以准确查看发送的内容,包括 cookie。另外,这是跨域吗?例如不同的端口?如果是这样需要添加withCredentials 来请求 还要检查服务器配置是否不需要每个请求的新令牌【参考方案2】:

注意:我是 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(...),导致了这个答案。

【讨论】:

以上是关于如何将 CSRF 令牌从 AngularJS 前端发送到 Spring REST 服务后端?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Django 在前端获取 CSRF 令牌以及如何在 Postman 中使用它

HTTP 状态 403 - 未找到预期的 CSRF 令牌

角度中的 CSRF 令牌与 Laravel 5 不同

如何将 POST 数据中的 CSRF 令牌传递给 Django?

CSRF 令牌丢失或不正确。 Django + AngularJS

如何使用 Django 和 AngularJS 创建 POST 请求(包括 CSRF 令牌)