Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ public BCryptPasswordEncoder passwordEncoder() {
"/contact/**",
"/error/**/*",
"/console/**",
"/signup"
"/signup",
"/api/csrf"
};

@Override
Expand Down
23 changes: 23 additions & 0 deletions UserFront/src/main/java/com/userFront/resource/CsrfResource.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.userFront.resource;

import org.springframework.http.ResponseEntity;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* Safe, unauthenticated request a client can issue before its first state-changing call
* so that the CSRF token repository writes the XSRF-TOKEN cookie. While CSRF protection
* is disabled in SecurityConfig no token is bound to the request and no cookie is written.
*/
@RestController
public class CsrfResource {

@GetMapping("/api/csrf")
public ResponseEntity<Void> csrf(CsrfToken token) {
if (token != null) {
token.getToken();
}
return ResponseEntity.noContent().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.userFront.resource;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

import com.userFront.config.SecurityConfig;
import com.userFront.service.UserServiceImpl.UserSecurityService;

@RunWith(SpringRunner.class)
@WebMvcTest(CsrfResource.class)
@Import(SecurityConfig.class)
public class CsrfResourceTest {

@Autowired
private MockMvc mockMvc;

@MockBean
private UserSecurityService userSecurityService;

/**
* Only the status is asserted: the XSRF-TOKEN cookie is written once CSRF protection
* is enabled with a cookie-based token repository, and is absent while it is disabled.
*/
@Test
public void csrfEndpointReturnsNoContentForAnonymousClient() throws Exception {
mockMvc.perform(get("/api/csrf"))
.andExpect(status().isNoContent());
Comment on lines +35 to +36

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Bootstrap cookie remains untested

The status-only test passes without issuing a token. When CSRF protection is enabled, a separate test must verify that an anonymous request receives the XSRF-TOKEN cookie.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is intentional, per COG-1159. CSRF is still disabled on Boot 1.5.4, so the ticket scopes this test to the 204 only. A cookie assertion would fail today. Asserting that XSRF-TOKEN is set belongs with W2, where SecurityConfig switches to CookieCsrfTokenRepository. I checked that flow manually on a throwaway local build: GET /api/csrf returned 204 with Set-Cookie: XSRF-TOKEN=…. The details are in the PR description.

}
}