CSRF protection depends on how the browser supplies credentials to the endpoint.
Spring Security bearer POST and CSRF: define the credential boundary
The fixture has no login cookie
The command test is a stateless bearer-token web context. A caller sends Authorization: Bearer explicitly; no server session or browser-sent Basic credential authenticates the POST. The fixture disables CSRF in that narrow context and requires receipt.write scope before the controller. The runnable ReceiptApplication is different: it retains Basic authentication and CSRF protection. Do not copy the fixture's CSRF setting into that application without changing its credential model.
A signed tenant-east token targeting tenant-west is rejected by a managed method rule. The X-Tenant header says tenant-west in the accepted east request yet cannot override the principal. The principal lesson explains claim mapping; the scope lesson separates filter and service denials.
State what the browser can attach
If a browser app stores a token in a cookie and sends it automatically, the threat changes. Authentication alone does not replace origin and CSRF decisions. CORS determines which browser origins may read responses; it is not request authorization. For a real release, document token storage, permitted origins, cookie attributes and the deployed gateway's header rules before choosing CSRF configuration.
Checked source
http.csrf(csrf -> csrf.disable())
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(requests -> requests
.requestMatchers("/contract/commands/**").hasAuthority("SCOPE_receipt.write"));Verification boundary
TenantReceiptCommandFlowTest.authorizedWriteCommitsReceiptOutboxAndReplayRecord and TenantReceiptCommandFlowTest.crossTenantAndWrongScopeAreDeniedBeforeMutation in the downloadable Spring source kit. The excerpt is shortened; the kit contains the complete test.
Costs and limits
The local test has no browser, cookie, gateway, origin-policy or deployed token store. Its result only checks the stated stateless bearer setup. The production CSRF decision needs the actual client and credential transport design.
Common Mistakes
- Do not disable CSRF in a cookie-authenticated application by copying this fixture.
- Do not treat CORS as authorization.
- Do not treat a signed token as permission for every tenant.
Read next
Spring Security filter chain: authentication, CSRF and request order, Spring Security JWT tenant principal: map only a validated claim, Spring Security scope versus tenant ownership: two separate decisions, Spring tenant command transaction: keep state, event and replay record together.
