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
70 lines
5.0 KiB
Plaintext
70 lines
5.0 KiB
Plaintext
==============================================================================
|
|
Demo 4 -- what you can actually write inside @PreAuthorize / @PostAuthorize
|
|
==============================================================================
|
|
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: ROLE_USER, ROLE_AUDITOR, plus the authority 'report:read'
|
|
----------------------------------------------------------------
|
|
permitAll ALLOWED -> ok
|
|
denyAll DENIED -> AuthorizationDeniedException: Access Denied
|
|
isAuthenticated() ALLOWED -> ok
|
|
isAnonymous() DENIED -> AuthorizationDeniedException: Access Denied
|
|
isFullyAuthenticated() ALLOWED -> ok
|
|
isRememberMe() DENIED -> AuthorizationDeniedException: Access Denied
|
|
hasRole('ADMIN') DENIED -> AuthorizationDeniedException: Access Denied
|
|
hasAnyRole('ADMIN','AUDITOR') ALLOWED -> ok
|
|
hasAllRoles('USER','AUDITOR') ALLOWED -> ok
|
|
hasAuthority('report:read') ALLOWED -> ok
|
|
hasAnyAuthority('report:read','x') ALLOWED -> ok
|
|
hasAllAuthorities('report:read','x') DENIED -> AuthorizationDeniedException: Access Denied
|
|
authentication.name == 'alice' ALLOWED -> ok
|
|
principal == 'alice' ALLOWED -> ok
|
|
|
|
root: ROLE_ADMIN only (RoleHierarchy says ADMIN > USER > GUEST)
|
|
---------------------------------------------------------------
|
|
permitAll ALLOWED -> ok
|
|
denyAll DENIED -> AuthorizationDeniedException: Access Denied
|
|
isAuthenticated() ALLOWED -> ok
|
|
isAnonymous() DENIED -> AuthorizationDeniedException: Access Denied
|
|
isFullyAuthenticated() ALLOWED -> ok
|
|
isRememberMe() DENIED -> AuthorizationDeniedException: Access Denied
|
|
hasRole('ADMIN') ALLOWED -> ok
|
|
hasAnyRole('ADMIN','AUDITOR') ALLOWED -> ok
|
|
hasAllRoles('USER','AUDITOR') DENIED -> AuthorizationDeniedException: Access Denied
|
|
hasAuthority('report:read') DENIED -> AuthorizationDeniedException: Access Denied
|
|
hasAnyAuthority('report:read','x') DENIED -> AuthorizationDeniedException: Access Denied
|
|
hasAllAuthorities('report:read','x') DENIED -> AuthorizationDeniedException: Access Denied
|
|
authentication.name == 'alice' DENIED -> AuthorizationDeniedException: Access Denied
|
|
principal == 'alice' DENIED -> AuthorizationDeniedException: Access Denied
|
|
|
|
Role prefix and hierarchy
|
|
-------------------------
|
|
hasRole('USER') -> ROLE_USER ALLOWED -> ok
|
|
hasAuthority('USER') -> literal 'USER' DENIED -> AuthorizationDeniedException: Access Denied
|
|
hasAuthority('ROLE_USER') ALLOWED -> ok
|
|
root hasRole('GUEST') via RoleHierarchy ALLOWED -> ok
|
|
|
|
Method arguments, the return value, and bean references
|
|
-------------------------------------------------------
|
|
#owner == authentication.name ("alice") ALLOWED -> ok
|
|
#owner == authentication.name ("bob") DENIED -> AuthorizationDeniedException: Access Denied
|
|
@P("o") alias, #o == ...name ("alice") ALLOWED -> ok
|
|
#root.this (the target object) ALLOWED -> ok
|
|
#root.args[0] -- no such property DENIED -> IllegalArgumentException: Failed to evaluate expression '#root.args[0] == authentication.name' [cause: SpelEvaluationException: EL1008E: Property or field 'args' cannot be found on object of type 'org.springframework.security.access.expression.method.MethodSecurityExpressionRoot' - maybe not public or not valid?]
|
|
@policy.canRead(authentication, #id) id=1 ALLOWED -> ok
|
|
@policy.canRead(authentication, #id) id=9 DENIED -> AuthorizationDeniedException: Access Denied
|
|
hasPermission(#id, 'account', 'read') id=1 ALLOWED -> ok
|
|
hasPermission(#id, 'account', 'read') id=9 DENIED -> AuthorizationDeniedException: Access Denied
|
|
T(java.time.LocalDate) type reference ALLOWED -> ok
|
|
@PostAuthorize returnObject.owner == ...name ALLOWED -> Account[1,alice,100]
|
|
@PostAuthorize returnObject.owner == ...name DENIED -> AuthorizationDeniedException: Access Denied
|
|
|
|
The literal constants on SecurityExpressionRoot
|
|
-----------------------------------------------
|
|
permitAll / denyAll exist as BOTH a boolean field and a no-arg method,
|
|
and read/write/create/delete/admin are String constants meant for
|
|
hasPermission(..) -- e.g. hasPermission(#id, 'account', read).
|
|
hasPermission(#id, 'account', read) id=1 ALLOWED -> ok
|