Tools

How to add X-XSRF-TOKEN header to Postman requests

When an API is secured against CSRF attacks, we must ensure that our clients’ requests are adjusted to the security requirements. Learn how to successfully call an API that uses the Cookie-to-header token approach by adding the X-XSRF-TOKEN header to Postman requests.

Debugging the “Invalid CSRF token” error

We get the Invalid CSRF token error when an API has csrf protection enabled and our request doesn’t contain the required data. The security configuration regarding the csrf protection in my example Spring Boot project looks like this:

public static void configureApiSecurity(HttpSecurity http) throws Exception {
        http
                .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
…

The Spring documentation describes the CookieCsrfTokenRepository as follows:

A CsrfTokenRepository that persists the CSRF token in a cookie named “XSRF-TOKEN” and reads from the header “X-XSRF-TOKEN”

https://docs.spring.io/spring-security/site/docs/5.0.13.RELEASE/api/index.html?org/springframework/security/web/csrf/CookieCsrfTokenRepository.html

As a result, the token will be present in the API responses as seen in the screenshot below:

Consequently, when I’m sending a POST request with no value provided in the required header, I get the 403 Forbidden in response. The exact error is specified in the application logs:

DEBUG 11528 --- [nio-8080-exec-3] o.s.security.web.csrf.CsrfFilter         : Invalid CSRF token found for http://localhost:8080/api/products
DEBUG 11528 --- [nio-8080-exec-3] o.s.s.w.access.AccessDeniedHandlerImpl   : Responding with 403 status code

In a Spring Boot application, we can debug the actual value that is checked in the CsrfFilter class:

In my case, the actual value is null. So I need to add the X-XSRF-TOKEN header to my Postman POST requests.

Add XSRF token to Postman requests

I’m going to configure my Postman collection to get the current token from each request and save it as an environment variable. Then, I will use this variable as the header value for my POST calls.

Save the token value as an environment variable

To read the value of the cookie, we’re going to execute a short JavaScript code in Postman.

The sample collection I’m using for this article is in my public Postman workspace and is part of my keycloak-spring-boot project. If you want to test my code locally (it requires Docker for running a Keycloak instance), visit the project repository on GitHub and follow the directions in the README.md file.

For all requests

First, I’m going to place the js code in the Collection testing space. As we can read in the documentation:

A test script associated with a collection will run after every request in the collection.

https://learning.postman.com/docs/writing-scripts/test-scripts/#testing-collections-and-folders

This way, I won’t have to add the script to every POST request I may create in this collection in the future.

I’m going to edit my example keycloak-spring-boot collection:

Then, I’m going to add the following code to the Tests tab:

var xsrfCookie = pm.cookies.get("XSRF-TOKEN");
pm.environment.set('xsrf-token', xsrfCookie);

You can see the result in the screenshot below:

Finally, I’m going to save the changes to the collection by clicking the Update button.

For a single request

Alternatively, I can only read the cookie after a selected request. To achieve this, I will need to add the js code in the request-specific test space and click the Save button. In summary, the configuration of a single request will look like this:

In this case, we must remember to add the js code to any future POST request as well.

Add the header

First, I’m going to verify that the value is actually available as an environment variable in Postman after running my request. Therefore, I’m going to execute the request, click on the Environment quick look button (the eye icon) and look for the xsrf-token variable as shown in the screenshot below:

Now I’m going to add a new header to my request, with the following data:

  • Key: X-XSRF-TOKEN,
  • Value: {{xsrf-token}}.

We can see the result in the screenshot below:

Verify the configuration

Finally, I can make my POST request with the certainty that it will work successfully:

Troubleshooting

What to check when API calls don’t work as planned?

403 Forbidden response status

  • The JavaScript code we add will only run after a request. Therefore, we will get 403 on the first API call since the cookie value is not yet set to a variable. However, subsequent requests will have the appropriate value in the header.
  • Is the {{xsrf-token}} variable set in Postman environment? You can see its current value in the Environment quick look or by hovering over the variable. Select the proper environment (localhost in my example) and make sure that the value is not empty.
  • Can you check API logs or debug the actual verified header value? If the value is null, the header is empty.
  • Remember that even if we add the script to a collection-specific test space, we need to manually add the X-XSRF-TOKEN header to each POST request.

More on complying with the CSRF requirements

Photo by Andrea Piacquadio from Pexels

little_pinecone

View Comments

    • I think it depends on the security configuration of the API you're trying to call.

      To test adding the token in Postman to call an API secured with Basic Auth:

      • clone the spring-boot-swagger-ui-basic-auth project and run the app locally;

      • select the Basic Auth Authorization Type and provide username and password (from the project's README.md);

      • follow the steps described in this article to add the token;

      • if the configuration works, the app returns 204 No Content response on the DELETE endpoint.

      Below is a screenshot from my Postman:

Recent Posts

Simplify the management of user roles in Spring Boot

Spring Security allows us to use role-based control to restrict access to API resources. However,…

3 years ago

Create a custom annotation to configure Spring Boot tests

A custom annotation in Spring Boot tests is an easy and flexible way to provide…

3 years ago

Keycloak with Spring Boot #4 – Simple guide for roles and authorities

Delegating user management to Keycloak allows us to better focus on meeting the business needs…

3 years ago

Keycloak with Spring Boot #3 – How to authorize requests in Swagger UI

Swagger offers various methods to authorize requests to our Keycloak secured API. I'll show you…

3 years ago

Keycloak with Spring Boot #2 – Spring Security instead of Keycloak in tests

Configuring our Spring Boot API to use Keycloak as an authentication and authorization server can…

3 years ago

Keycloak with Spring Boot #1 – Configure Spring Security with Keycloak

Keycloak provides simple integration with Spring applications. As a result, we can easily configure our…

3 years ago