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
38 lines
2.5 KiB
Plaintext
38 lines
2.5 KiB
Plaintext
==============================================================================
|
|
Demo 3 -- @PreAuthorize on methods the proxy cannot override
|
|
==============================================================================
|
|
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.
|
|
|
|
alice has ROLE_USER. Every method below says hasRole('ADMIN').
|
|
--------------------------------------------------------------
|
|
public (overridable) DENIED -> AuthorizationDeniedException: Access Denied
|
|
public final (NOT overridable) ALLOWED -> final payload
|
|
static (NOT overridable) ALLOWED -> static payload
|
|
package-private (overridable, same package) DENIED -> AuthorizationDeniedException: Access Denied
|
|
private, reached via a public wrapper ALLOWED -> private payload
|
|
|
|
What the proxy actually overrode
|
|
--------------------------------
|
|
publicAdminOnly declared final=false overridden by proxy=true
|
|
finalAdminOnly declared final=true overridden by proxy=false
|
|
packagePrivateAdminOnly declared final=false overridden by proxy=true
|
|
proxy class -> com.ankurm.methodsec.Demo3NonProxyable$Vault$$SpringCGLIB$$0
|
|
|
|
A JDK dynamic proxy only advises methods that are ON the interface
|
|
------------------------------------------------------------------
|
|
proxy is a JDK proxy -> true
|
|
proxied interfaces -> [interface com.ankurm.methodsec.Demo3NonProxyable$LedgerOperations]
|
|
onTheInterface() (advised) DENIED -> AuthorizationDeniedException: Access Denied
|
|
notOnTheInterface() is public and annotated, but the JDK proxy does not
|
|
implement it at all -- a caller cannot even reach it without casting to
|
|
the implementation class, and that cast throws ClassCastException.
|
|
cast proxy to Ledger impl class DENIED -> ClassCastException: class jdk.proxy2.$Proxy18 cannot be cast to class com.ankurm.methodsec.Demo3NonProxyable$Ledger (jdk.proxy2.$Proxy18 is in module jdk.proxy2 of loader 'app'; com.ankurm.methodsec.Demo3NonProxyable$Ledger is in unnamed module of loader 'app')
|
|
|
|
A final CLASS is the loud one
|
|
-----------------------------
|
|
startup FAILED -> BeanCreationException
|
|
root cause -> java.lang.IllegalArgumentException
|
|
message -> Cannot subclass final class com.ankurm.methodsec.Demo3NonProxyable$SealedVault
|