Angularjs Spring Security cookie仅在第一个禁止请求之后到达

Angularjs Spring Security cookie仅在第一个禁止请求之后到达,angularjs,spring-security,angular-cookies,Angularjs,Spring Security,Angular Cookies,我正在使用Spring安全性来保护我的Spring Data REST Web应用程序与AngularJS 我的SecurityConfig声明如下: @Override protected void configure(HttpSecurity http) throws Exception { http .httpBasic().and() .authorizeRequests() // public ressources .antMatcher

我正在使用Spring安全性来保护我的Spring Data REST Web应用程序与AngularJS

我的SecurityConfig声明如下:

@Override
protected void configure(HttpSecurity http) throws Exception {

  http
    .httpBasic().and()
    .authorizeRequests()
    
    // public ressources
    .antMatchers("/index.html", "/templates/public/**", "/js/**", "/").permitAll()
    .antMatchers(HttpMethod.GET, "/api/security/user").permitAll()
    .antMatchers("/api/**").hasAnyRole("ADMIN", "NORMALUSER")
    
    .anyRequest().authenticated()
    .and().exceptionHandling().authenticationEntryPoint(basicAuthenticationEntryPointHandler)
    
    .and().logout().logoutUrl("/logout").logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler()).deleteCookies("JSESSIONID").permitAll().and()
    .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
为了达到我的目标,我一般都会跟随林克

现在,如果我第一次登录自己,对
$cookies.get(“XSRF-TOKEN”)
的角度请求返回未定义,并且对我的数据库的每个请求都不会被阻止

但是在注销并再次登录之后,它会返回cookie,并且允许每个数据库请求

而且这种情况只会在登录后的每一秒发生,因此:

  • 未定义

  • 饼干

  • 未定义

  • 饼干

  • 未定义

  • 所以现在我希望有人能在不深入我的结构的情况下帮助我,但如果需要的话,我会这么做

    提前谢谢

    编辑1:以下是请求:

    与流程相关:我将令牌记录在我的CokieCsrfTokenRepository().loadToken()中,所有令牌都显示在这里

    编辑2:我的Angular Service,我每次登录都会调用它:

    function authenticationService($rootScope, $http, $location, $filter, $cookies){    
        function authenticate(credentials, callback) {
    
            var headers = credentials ? {authorization : "Basic "
                + btoa(credentials.username + ":" + credentials.password)
            } : {};
    
            $http.get('api/security/user', {headers : headers}).success(function(data, status, get, header) {
                if (data.name) {
                    $rootScope.authenticated = true;
                    $rootScope.session = data;
                    console.log($cookies.get("XSRF-TOKEN")) // -> returns every second login cookie
                    
                } else {
                    $rootScope.authenticated = false;
                    $rootScope.session = null;
                }
                
                console.log($rootScope.session)
                
                callback && callback();
            }).error(function() {
                $rootScope.authenticated = false;
                
                callback && callback();
            });
            
        }
        
        return {
            authenticate: function(credentials){
                authenticate(credentials, function() {
                    if ($rootScope.authenticated == true) {
                        $rootScope.authenticationError = false;
                        
                        if ($rootScope.session.principal.admin == true){
                            $location.path("/admin/manage");
                        } else{
                            $location.path("/user");
                        }
                    } else {
                        $rootScope.authenticationError = true;
                        
                        $location.path("/login");
                    }
                });
            },
            // called by refreshing browser
            checkLoggedIn: function(){
                authenticate();
            },
            
            logout: function(){
                $http.post('/logout', {})["finally"](function() {
                    $rootScope.authenticated = false;
                    $rootScope.session = null;
                    $location.path("/login");
                });
            }
        };
    }
    
    编辑3:我现在提到,如果cookie未定义,则只有在注销并刷新浏览器(首次登录)后才会调用loadToken()from link方法。然后显示令牌,我再次登录。但是每一秒尝试一次,它仍然很有效

    编辑4:所以我没有意识到,在第一次禁止发布请求(在Edit3中是/logout)之后,令牌到达了我的模板。刷新浏览器后,允许所有我的请求,因为现在每个请求都会发送cookie。但是如何解决这个问题呢?

    我的解决方案:

    //WebSecurityConfigurerAdapter:
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        ....
        .addFilterAfter(new CsrfCustomFilter(), CsrfFilter.class).and()
        .csrf().csrfTokenRepository(csrfTokenRepository());
    }
    
    private CsrfTokenRepository csrfTokenRepository() {
        HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
        repository.setHeaderName("X-XSRF-TOKEN");
        return repository;
    }
    
    public class CsrfCustomFilter extends 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);
        }
    }