当前位置: 首页 > 知识库问答 >
问题:

POST请求中的CSRF令牌无效

单于轶
2023-03-14

概述
我将使用API网关作为基于Spring Security性的身份验证。我刚刚按照https://spring.io/guides/tutorials/spring-security-and-angular-js/链接中的步骤创建了一个基于其对应的github项目的“对双”模块的项目https://github.com/spring-guides/tut-spring-security-and-angular-js.git.

问题< br >问题在于,当任何POST请求提交到服务器时,都会引发“无效的CSRF令牌”异常。引发异常的一个示例如下:< br >

{
  "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请求的标头,但什么都没有发生。

因此,由于我是使用Spring Security方法的初学者,如果有人能给我建议一个解决方案,我将不胜感激。

共有1个答案

卞经业
2023-03-14

查看该项目的安全配置,您会注意到使用过滤器在每个请求中添加了一个XSRF-TOKENcookie。因此,您需要做的是获取该cookie的值并将其存储在X-XSRF-TOKEN标头中。我用类似的安全配置做了一个测试项目来测试这个案例,完整的代码如下:

@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!";
    }
}

要使用邮递员进行测试,请执行以下操作:

  • 启用拦截器以开始捕获 Cookie。
  • 执行 GET /test 请求并打开 cookie 选项卡。在那里,您应该注意到一个名为XSRF-TOKEN的cookie。
  • 获取该 cookie 的值并将其放入 X-XSRF-TOKEN 标头中,然后执行 POST /test 请求。
 类似资料:
  • 我正在使用Amazon SNS在我的HTTP/HTTPSendpoint上接收推送消息。endpoint应用程序是用Django编写的。要在endpoint(web app)上接收通知,HTTP/HTTPSendpoint需要订阅一个主题。 我的问题是当Amzaon SNS发送订阅确认时,它如何在POST请求中发送CSRF令牌,以便我处理请求并检索所需信息? 文档:http://docs.aws.

  • 我正在尝试通过Ajax从数据库中删除数据。 HTML: 我的ajax代码: 这是我要从数据库中提取数据的查询... 但当我单击“删除链接数据未删除”并显示csrf_token不匹配时...

  • 我遇到了CodeIgniter/CSRF/JSON的问题。 我正在向PHP后端发送内容类型为“application/json”的http POST请求。有效负载是json数据。我将与数据一起传递生成并存储在CSRF cookie中的CSRF令牌。对于标准POST表单请求,它工作正常,但作为json发送时失败。 由于$\u POST数组因JSON内容类型而为空,CodeIgniter无法验证coo

  • 问题内容: 我试图通过ajax从数据库中删除数据。 HTML: 我的ajax代码: 这是我从数据库中获取数据的查询… 但是当我单击删除链接数据未删除并显示csrf_token不匹配… 问题答案: 您必须在ajax请求中添加 数据 。我希望这样会有用。

  • 我的rails应用程序订阅了一个外部系统POST通知(名为Orion context broker)。我管理发送json数据和处理响应(Ruby->Orion)。

  • 问题内容: 我正在使用Laravel 5应用程序,该应用程序默认为所有POST请求启用CSRF保护。我喜欢这种增加的安全性,因此我正在尝试使用它。 发出简单请求时,我收到一个错误,因为POST数据中缺少所需的表单输入。这是一个有关$ .post请求的示例: 我将CSRF令牌存储为标头中的meta字段,可以使用以下命令轻松访问它: 是否可以在所有传出请求中将其附加到json数据?我尝试使用标头,但L