1
0

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
This commit is contained in:
2026-08-25 02:01:29 +00:00
parent 9f950bffa9
commit 5e9e7f1b12
65 changed files with 4088 additions and 119 deletions

View File

@@ -0,0 +1,50 @@
==============================================================================
Demo 1 -- the four pre/post annotations, @Secured and JSR-250, all switched on
==============================================================================
SLF4J(W): No SLF4J providers were found.
SLF4J(W): Defaulting to no-operation (NOP) logger implementation
SLF4J(W): See https://www.slf4j.org/codes.html#noProviders for further details.
as alice (ROLE_USER)
--------------------
@PreAuthorize hasRole('ADMIN') DENIED -> AuthorizationDeniedException: Access Denied
@PreAuthorize #owner == authentication.name ALLOWED -> [Account[1,alice,100], Account[3,alice,300]]
@PreAuthorize #owner == authentication.name DENIED -> AuthorizationDeniedException: Access Denied
@PostAuthorize returnObject.owner == ...name ALLOWED -> Account[1,alice,100]
@PostAuthorize returnObject.owner == ...name DENIED -> AuthorizationDeniedException: Access Denied
@PostFilter filterObject.owner == ...name ALLOWED -> [Account[1,alice,100], Account[3,alice,300]]
@Secured("ROLE_ADMIN") DENIED -> AuthorizationDeniedException: Access Denied
@RolesAllowed("ADMIN") DENIED -> AuthorizationDeniedException: Access Denied
@PermitAll ALLOWED -> open payload
@DenyAll DENIED -> AuthorizationDeniedException: Access Denied
as root (ROLE_ADMIN, ROLE_USER)
-------------------------------
@PreAuthorize hasRole('ADMIN') ALLOWED -> the admin console
@Secured("ROLE_ADMIN") ALLOWED -> secured payload
@RolesAllowed("ADMIN") ALLOWED -> jsr250 payload
@PostFilter filterObject.owner == ...name ALLOWED -> []
with no Authentication at all (SecurityContextHolder cleared)
-------------------------------------------------------------
@PreAuthorize hasRole('ADMIN') DENIED -> AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
@PermitAll ALLOWED -> open payload
@PreFilter -- filtering the ARGUMENT, as alice
----------------------------------------------
caller's list before the call : [Account[1,alice,100], Account[2,bob,200], Account[3,alice,300]]
method body saw : [Account[1,alice,150], Account[3,alice,350]]
caller's list after the call : [Account[1,alice,150], Account[3,alice,350]]
@PreFilter did not hand the method a copy. It removed bob's account from
the caller's own list, in place, before the method body ever ran. That is
why Demo 5's immutable List.of(..) blows up.
@PreFilter on a method with more than one argument
--------------------------------------------------
no filterTarget, 2 args DENIED -> IllegalStateException: Unable to determine the method argument for filtering. Specify the filter target.
method body saw : [Account[4,alice,60]]
filterTarget = "accounts" ALLOWED -> (void)
This one is loud, not silent -- but it only fires when the method is
actually called, so a rarely-exercised path can ship broken.