POST请求中的CSRF令牌无效 [英] Invalid CSRF Token in POST request

查看:1509
本文介绍了POST请求中的CSRF令牌无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

概述
我将使用API​​网关作为基于Spring安全性的身份验证.我一直在遵循 https://spring中的步骤. io/guides/tutorials/spring-security-and-angular-js/链接可基于其

Overview
I am going to use API Gateway as the authentication which based on Spring security. I've just been following the steps in the https://spring.io/guides/tutorials/spring-security-and-angular-js/ link to create a project based on "pairs-double" module of its corresponding github project of https://github.com/spring-guides/tut-spring-security-and-angular-js.git.

问题
问题在于,当任何POST请求提交到服务器时,都会引发无效的CSRF令牌"异常.引发异常的示例如下:

Problem
The issue is the fact that when any POST request is submitted to the server the "Invalid CSRF Token" exception is thrown. An example of the thrown exception is as follows:

{
  "timestamp": 1461714933215,
  "status": 403,
  "error": "Forbidden",
  "message": "Invalid CSRF Token '1cdc44ad-43cb-44e6-b903-bec24fe903fd' was found on the request parameter '_csrf' or header 'X-XSRF-TOKEN'.",
  "path": "/ui/test"
}

我检查了问题,但无济于事.我用邮递员测试了这种情况,并将"X-XSRF-TOKEN"设置为POST请求的标头,但没有任何反应.

I checked an rechecked the issue but to no avail. I tested this scenario with postman and set the 'X-XSRF-TOKEN' as the header of the POST request but nothing happened.

因此,作为我刚开始使用Spring安全性方法的人,如果有人可以向我建议解决方案,我将不胜感激.

So, as I am beginner in using Spring security approaches, I would appreciate it if anyone could suggest me a solution.

推荐答案

查看该项目的安全配置,您会注意到在每个请求中都添加了XSRF-TOKEN cookie

Looking at the security configuration of that project, you will notice that a XSRF-TOKEN cookie is being added in each request using a filter. So what you have to do is take the value of that cookie and store it in X-XSRF-TOKEN header. I've made a test project with similar security configuration to test out this case, the complete code looks like this:

@RestController
@SpringBootApplication
public class TestApplication extends WebSecurityConfigurerAdapter {

    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .antMatchers("/**")  // Disable authentication for all requests.
            .permitAll()
            .and()
            .csrf().csrfTokenRepository(csrfTokenRepository())
            .and()
            .addFilterAfter(csrfHeaderFilter(), SessionManagementFilter.class); // Register csrf filter.
    }

    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())) {

                        // Token is being added to the XSRF-TOKEN cookie.
                        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;
    }

    @RequestMapping(value = "/test", method = RequestMethod.GET)
    public String testGet() {
        return "hello";
    }

    @RequestMapping(value = "/test", method = RequestMethod.POST)
    public String testPost() {
        return "works!";
    }
}

要与邮递员进行验证,请执行以下操作:

To test this out with postman do the following:

  • 启用拦截器开始捕获cookie.
  • 执行GET /test请求并打开cookie选项卡.在那里,您应该注意到一个名为XSRF-TOKEN的cookie.
  • 获取该cookie的值并将其放在X-XSRF-TOKEN标头中并执行POST /test请求.
  • Enable interceptor to start capturing cookies.
  • Perform a GET /test request and open the cookies tab. There you should notice a cookie with a name XSRF-TOKEN.
  • Take the value of that cookie and put it in X-XSRF-TOKEN header and perform a POST /test request.

这篇关于POST请求中的CSRF令牌无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆