带有 AngularJS 的 Spring Boot 和 CSRF - Forbitten 403 -> 错误注销

Posted

技术标签:

【中文标题】带有 AngularJS 的 Spring Boot 和 CSRF - Forbitten 403 -> 错误注销【英文标题】:Spring Boot and CSRF with AngularJS - Forbitten 403 -> wrong logout 【发布时间】:2017-03-07 05:20:20 【问题描述】:

在我的 Spring Boot/AngularJS 应用程序中,我有以下 CSRF- 配置:

@Override
protected void configure(final HttpSecurity http) throws Exception 
    http.csrf().csrfTokenRepository(csrfTokenRepository());    http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

    final String[] restEndpointsToSecure = WebSecurityConfig.restEndpointsToSecure;
    for (final String endpoint : restEndpointsToSecure) 
        http.authorizeRequests().antMatchers("/" + endpoint + "/**").hasRole(UserRoleEnum.USER.toString());
    

    http.addFilterAfter(csrfTokenResponseHeaderBindingFilter(), CsrfFilter.class);

    xAuthTokenConfigurer.setDetailsService(userDetailsServiceBean());
    final SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity> securityConfigurerAdapter = xAuthTokenConfigurer;
    http.apply(securityConfigurerAdapter);

CSRF- Token Filter 如下所示:

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, javax.servlet.FilterChain filterChain)
        throws ServletException, IOException 

    final CsrfToken csrf = (CsrfToken)request.getAttribute(CsrfToken.class.getName());
    if (csrf != null) 
        Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
        final 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);

通常它工作正常,请求头属性 X-XSRF-TOKEN 随每个请求一起发送。但我有一个奇怪的行为。 我将在应用程序中更新我的用户配置文件。第一次工作正常,第二次,我得到一个 HTTP 403 Forbidden,实际上我真的不知道为什么。 我在这两个更新之间什么都不做(在这两个更新之间没有导航到其他页面或其他)。

在底部的图片中,左边的请求有效,右边的请求失败。唯一不同的是,右侧的属性 Set-CookieX-Application-context 在响应标头中丢失。请求头是相等的。

有谁知道我在这里做错了什么。这对我来说有点神秘。

【问题讨论】:

你能发布你的角度代码吗?特别是您的角度路线代码。 这是对任何资源的任何第二次尝试的常见行为还是仅用于配置文件更新? 【参考方案1】:

您的front-end 中似乎可能有一些功能性error userProfile.controller

您从 请求标头 重定向的 Cookie SessionID响应标头 中变得相同,导致 INVALID_SESSIONID因此用户被重定向登录页面或您的注册页面

作为解决方案,您可以纠正您的前端控制器,或者作为另一种解决方法,您可以将以下内容添加到您的代码中

仅在检测到 CORS 时添加 CORS 标头并传递源标头,以便允许访问用户内容。

使用 http 200 消息响应 OPTIONS 请求

 static final String ORIGIN = "Origin";

if (request.getHeader(ORIGIN).equals("null")) 
        String origin = request.getHeader(ORIGIN);
        response.setHeader("Access-Control-Allow-Origin", "*");//* or origin as u prefer
        response.setHeader("Access-Control-Allow-Credentials", "true");
       response.setHeader("Access-Control-Allow-Headers",
                request.getHeader("Access-Control-Request-Headers"));
    
    if (request.getMethod().equals("OPTIONS")) 
        try 
            response.getWriter().print("OK");
            response.getWriter().flush();
         catch (IOException e) 
            e.printStackTrace();
        
    

然后添加要调用的自定义过滤器

      //your other configs
      < security:custom-filter ref="corsHandler" after="PRE_AUTH_FILTER"/>

threadauthor 的答案完全归属于这个author

【讨论】:

感谢您的回复。 ** 前端控制器 ** 中可能有什么问题,如果它第一次工作? 第一次登录的session ID不同,不冲突,但第二次尝试更新anfrage header的session ID与antwort header冲突,好像放一样,因此它提供无效的会话 ID 并由于安全错误而注销

以上是关于带有 AngularJS 的 Spring Boot 和 CSRF - Forbitten 403 -> 错误注销的主要内容,如果未能解决你的问题,请参考以下文章

带有 spring-boot 和 angularjs 的 CORS 不起作用

带有 Spring Security 的 AngularJS Web 应用程序

带有 ROLE_ANONYMOUS 的 AngularJS 和 Spring Security 仍然返回 401

带有 AngularJS 的 Spring Boot 和 CSRF - Forbitten 403 -> 错误注销

带有 angularJS web 应用程序和 android 应用程序的 spring 安全性

Spring Security AngularJS 登录