Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing controllers with CSRF protection enabled in Spring security

Recently we have introduced CSRF protection for our project which uses spring security 3.2.

After enabling CSRF some of the unit tests are failing because of the csrf token is not present in request. I put some dummy value into '_csrf' parameter and it didn't work.

Is there anyway that I can get the csrf token before sending the request (when unit testing)?

like image 200
uiroshan Avatar asked Sep 01 '14 11:09

uiroshan


People also ask

How CSRF is implemented in Spring Security?

To protect MVC applications, Spring adds a CSRF token to each generated view. This token must be submitted to the server on every HTTP request that modifies state (PATCH, POST, PUT and DELETE — not GET). This protects our application against CSRF attacks since an attacker can't get this token from their own page.

Is CSRF enabled by default in Spring Security?

As of Spring Security 4.0, CSRF protection is enabled by default with XML configuration.

How do I get CSRF token in Spring Security?

You can obtain the CSRF using the request attribute named _csrf as outlined in the reference. To add the CSRF to an HTML page, you will need to use JavaScript to obtain the token that needs to be included in the requests.


1 Answers

The way to solve this issue is :

import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*;  ...  @Test public void testLogin() throws Exception {     this.mockMvc.perform(post("/login")             .param("username", "...")             .param("password", "...")             .with(csrf()))         .andExpect(status().isFound())         .andExpect(header().string("Location", "redirect-url-on-success-login")); } 

The important part is : .with(csrf()) which will add the expected _csrf parameter to the query.

The csrf() static method is provided by spring-security-test :

<dependency>     <groupId>org.springframework.security</groupId>     <artifactId>spring-security-test</artifactId>     <version>5.3.5.RELEASE / 5.4.1</version>     <scope>test</scope> </dependency> 

Your unit test will require the following import to access it:

 import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*; 
like image 138
Thierry Avatar answered Sep 20 '22 16:09

Thierry