Method authorization intercepts a service invocation and evaluates an access rule before the protected method executes.
Spring method authorization: test the proxied service boundary
The downloadable Spring source kit pins Java 21 and Spring Boot 4.0.8 with its managed dependencies. Run mvn test to check the named fixture.
Protect the service operation
AuthorizedReceiptRead requires receipt:read through PreAuthorize. The configuration explicitly enables method security, then the test obtains the bean from the context. A caller with that authority receives receipt:7; an authenticated caller without it receives AccessDeniedException. Authentication and authorization are separate questions.
The test installs a SecurityContext only for its local invocation and clears it in finally. It does not verify a login flow, tokens, sessions or a persistent identity store. HTTP filter rules remain necessary because they govern the request boundary that calls this service.
An annotation does not protect every Java object
The test also constructs AuthorizedReceiptRead directly. That object returns the receipt because it has no method-security proxy. This is intentional evidence of the boundary: an annotation is metadata, while interception supplies the enforcement path. Do not expose an unproxied copy of the service as a bypass.
The authority rule permits reading receipts in general. It does not prove ownership of receipt seven or enforce tenant membership. Add resource-specific authorization using trusted identity and repository state when the domain requires it. A route parameter supplied by the caller is not evidence of permission.
Checked source
package in.aitrove.contracts;
import org.springframework.security.access.prepost.PreAuthorize;
public class AuthorizedReceiptRead {
@PreAuthorize("hasAuthority('receipt:read')")
public String receipt(long id) { return "receipt:"+id; }
}Test the boundary
FrameworkBoundaryTest.methodProxyChecksAuthorityAndDirectObjectDoesNot checks this contract in the source kit. Excerpts belong to the named classes; use the downloadable files for imports, configuration and assertions.
Costs and boundaries
Each call evaluates a rule through the configured interceptor. A rule consulting a database adds its own latency and failure path. This local authority check contains no tenant query and should not be advertised as object-level access control.
Common Mistakes
- Enable method security and test the bean obtained from the context.
- Do not assume direct construction enforces the annotation.
- Do not confuse a general authority with ownership of a particular record.
Read next
Spring Security filter chain: authentication, CSRF and request order, Spring AOP proxies: self-invocation bypasses proxy advice, Spring tests: separate business rules, wiring and transport, Java interfaces and replaceable behavior.
Extend the tested workflow
Continue with Spring Security JWT resource server: validate trust before checking scope.
Continue with the new boundary checks
Continue with Spring method authorization: reject a cross-tenant read.
Continue with checked Spring boundaries
Continue with Spring Security roles and authorities: check the actual granted string.
