java – HTTP状态403 – 在请求参数上找到无效的CSRF令牌“null”

我必须向我的restful服务发出HTTP.Post(Android App),以注册新用户!

问题是,当我尝试向注册终端发出请求(没有安全性)时,Spring一直阻止我!

我的项目依赖关系

春季安全

调节器

@RestController
@RequestMapping(value="/webapi/cadastro",produces="application/json")
public class CadastroController {
    @Autowired 
    UsuarioService usuarioService;

    Usuario u = new Usuario();

    @RequestMapping(value="/novo",method=RequestMethod.POST)
    public String register() {
        // this.usuarioService.insert(usuario);
        // usuario.setPassword(HashMD5.criptar(usuario.getPassword()));
        return "teste";
     }
}

JS Post(Angular)

$http.post('/webapi/cadastro/novo').success(function(data) {
            alert('ok');
         }).error(function(data) {
             alert(data);
         });

而错误

HTTP Status 403 - Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-XSRF-TOKEN'.

—解决方案—

实现了一个过滤器,将我的X-XSRF-TOKEN连接到每个请求标头

public class CsrfHeaderFilter 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);
  }
}

添加到此过滤器的映射到web.xml并完成!

最佳答案
在上面的代码中,我看不到会将CSRF令牌传递给客户端的东西(如果你使用JSP等,这是自动的).

一种流行的做法是编写过滤器以将CSRF令牌作为cookie附加.然后,您的客户端首先发送GET请求以获取该cookie.对于后续请求,该cookie随后将作为标头发回.

官方Spring Angular guide详细说明了这一点,您可以参考Spring Lemon获取完整的工作示例.

要将cookie作为标题发回,您可能需要编写一些代码.默认情况下,AngularJS会这样做(除非您发送跨域请求),但这里有一个示例,如果它有助于您的客户端不这样做:

angular.module('appBoot')
  .factory('XSRFInterceptor',function ($cookies,$log) {

    var XSRFInterceptor = {

      request: function(config) {

        var token = $cookies.get('XSRF-TOKEN');

        if (token) {
          config.headers['X-XSRF-TOKEN'] = token;
          $log.info("X-XSRF-TOKEN: " + token);
        }

        return config;
      }
    };
    return XSRFInterceptor;
  });

angular.module('appBoot',['ngCookies','ngMessages','ui.bootstrap','vcRecaptcha'])
    .config(['$httpProvider',function ($httpProvider) {

      $httpProvider.defaults.withCredentials = true;
      $httpProvider.interceptors.push('XSRFInterceptor');

    }]);

相关文章

这篇文章主要介绍了spring的事务传播属性REQUIRED_NESTED的原...
今天小编给大家分享的是一文解析spring中事务的传播机制,相...
这篇文章主要介绍了SpringCloudAlibaba和SpringCloud有什么区...
本篇文章和大家了解一下SpringCloud整合XXL-Job的几个步骤。...
本篇文章和大家了解一下Spring延迟初始化会遇到什么问题。有...
这篇文章主要介绍了怎么使用Spring提供的不同缓存注解实现缓...