1
0
Files
asmhatre 5e9e7f1b12 Split into per-article modules and add the method-security module
Moves the existing virtual-thread/context-propagation project into
context-propagation/ and adds method-security/ for the Spring Security 7
method-security article: nine runnable demos, fourteen assertions, and every
transcript the article quotes, regenerated by scripts/run-all.sh.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RSrsDSRKVsY588yFiMJMo9
2026-08-25 02:01:29 +00:00
..

method-security

Companion module for Method Security in Spring Security 7: @PreAuthorize, @PostAuthorize and the Proxy Traps on ankurm.com.

Nine small programs and a JUnit suite, each answering one question about what @PreAuthorize and its siblings actually do at runtime — including the three cases where they do nothing at all and say nothing about it. No web layer, no Boot application, no server: a plain AnnotationConfigApplicationContext, a SecurityContextHolder, and real proxied beans, so every result is about method security and not about a filter chain.

Part of spring-security-demo; the sibling module is context-propagation.

Verified versions

Component Version
JDK 25 (Temurin 25.0.4.1+1), LTS
Spring Boot (reference target) 4.1.1
Spring Framework 7.0.9
Spring Security 7.1.1 (-core, -config, -test)
AspectJ Weaver 1.9.25 (only for exposeProxy in Demo 2)
Spring Data Commons 4.1.1 (only so Demo 5 can filter a real Page)
H2 2.4.240 (Demo 6's transaction rollback proof)
JUnit Jupiter 6.0.3
AssertJ 3.27.7

Latest GA on Maven Central at the time of writing, taken from maven-metadata.xml. 4.2.0-M1 / 7.2.0-M1 exist as milestones only.

Quickstart

mvn dependency:build-classpath -Dmdep.outputFile=cp.txt
javac --release 25 -parameters -cp "$(cat cp.txt)" -d target/classes $(find src/main -name '*.java')
java -cp "target/classes:$(cat cp.txt)" com.ankurm.methodsec.Demo2SelfInvocation

-parameters matters: without it every #parameterName expression in this module silently stops working, which is what Demo 9 is about.

Everything at once, regenerating docs/output/: scripts/run-all.sh. Just the assertions: mvn test.

What each demo shows

Demo Question Chapter
Demo1AnnotationsInAction What do all six annotation families do on the happy path, and what is thrown when they deny? docs/01
Demo2SelfInvocation Why does an annotated method called from inside its own class run unchecked, and what are the three fixes? docs/03
Demo3NonProxyable Which of final / static / private / package-private / final-class / interface-only actually get advised? docs/04
Demo4SpelReference Every expression you can write inside the annotation, evaluated as two different users docs/02
Demo5FilteringTraps Which container types can @PreFilter / @PostFilter handle, and what happens on an immutable one? docs/05
Demo6InterceptorOrder Where does the security advice sit relative to @Transactional, and does a denial roll back? docs/07
Demo7DeniedHandling What is actually thrown, and how do @HandleAuthorizationDenied and @AuthorizeReturnObject change it? docs/06
Demo8MetaAnnotations Do {value} templates need a bean? What does a method-level rule do to a class-level one? docs/08
Demo9ParameterNames The same class compiled with and without -parameters docs/02
MethodSecurityTrapsTest 14 assertions pinning every claim above docs/09

Captured output

File From
docs/output/demo1.txtdemo8.txt the eight demos above
docs/output/demo9-with-parameters.txt Demo 9, compiled with -parameters
docs/output/demo9-without-parameters.txt Demo 9, same source, compiled without it
docs/output/tests.txt mvn test

Regenerate all of it with scripts/run-all.sh. Nothing in docs/ or in the article is hand-typed output.

Documentation corrections found while building this

Each of these disagrees with the current reference documentation or with widely repeated guidance, and each was verified by running the code or reading the 7.1.1 source:

  • @EnableMethodSecurity has an offset attribute, not order.
  • AuthorizationProxyFactory is in org.springframework.security.authorization, not …authorization.method.
  • AbstractSecurityExpressionHandler.setRoleHierarchy(..) is deprecated in 7.1; AuthorizationManagerFactory is where role hierarchy and role prefix now live.
  • {value} meta-annotation templates work without an AnnotationTemplateExpressionDefaults bean.
  • Conflicting @PreAuthorize inherited from two interfaces fails at call time, not at startup.
  • @PreFilter on an immutable collection is a silent no-op, not an exception.
  • Package-private methods are advised by a CGLIB proxy.

See docs/09 for the full index.

License

MIT — see LICENSE.