A controller assertion is not an authorization test unless the request passes through the configured security chain.
Spring MockMvc security test: run the application filter chain
Keep the filter path real
A controller test calls a handler with a mocked principal and gets the expected JSON. That does not show whether the deployed SecurityFilterChain permits the route, checks a bearer token, or rejects a missing tenant claim. Build MockMvc from the application context with security filters active, or use a full-context auto-configured MockMvc. Standalone setup] is useful for mapping logic but needs explicit filter wiring.
Assert a denial matrix
Send an anonymous request, a caller with a valid identity but missing authority, and a caller with authority for the wrong tenant. Assert status and absence of writes for each. A helper that injects a mock JWT can exercise authorization rules, but it skips cryptographic token decoding; use a separate test for the decoder configuration. JWT web-context tests] and filter-chain rules] divide those responsibilities.
Watch the service boundary
A passing HTTP 403 does not prove a scheduled job or message listener is protected. Test method authorization] through a Spring-injected bean as well. For the web test, verify that a rejected request does not call the write service. Avoid mocking the SecurityFilterChain itself; doing so removes the behavior under examination.
Implementation contract
@SpringBootTest
@AutoConfigureMockMvc
class ReceiptAuthorizationHttpTest {
@Autowired MockMvc mvc;
@Test void rejectsMissingWriteAuthority() throws Exception {
mvc.perform(post("/receipts")
.with(jwt().authorities(
new SimpleGrantedAuthority("SCOPE_receipt.read")))
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content("{\"externalKey\":\"R-47\",\"minorUnits\":4700}"))
.andExpect(status().isForbidden());
}
}Cost and verification
A full-context MockMvc test starts more beans than a web slice and still avoids a real network port. Keep a small denial matrix here; use focused service tests for detailed tenant and policy permutations.
Common Mistakes
- Do not bypass the filter chain and call the result an HTTP authorization test.
- Do not treat a mock JWT as proof of signature or issuer validation.
- Do not rely only on controller security when non-web callers reach the same service.
Read next
Spring Security filter chain: authentication, CSRF and request order, Test Spring JWT authorization through filters, service proxy and SQL, Spring MockMvc standalone tests: know which HTTP layers were assembled, Spring method security: authorization advice runs through the bean proxy, Spring Boot HTTP test: client rollback does not own server writes.
