============================================================================== Demo 7 -- @HandleAuthorizationDenied and @AuthorizeReturnObject ============================================================================== 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. The exception type you actually catch ------------------------------------- thrown -> org.springframework.security.authorization.AuthorizationDeniedException is AccessDeniedException -> true is AuthorizationDeniedException -> true carries an AuthorizationResult -> ExpressionAuthorizationDecision granted=false Handlers written against AccessDeniedException still work -- but the concrete type carries the AuthorizationResult that explains the denial. @HandleAuthorizationDenied: return something instead of throwing ---------------------------------------------------------------- maskedBalance() (alice, no ROLE_FINANCE) ALLOWED -> ***masked*** maskedList() (alice, no ROLE_FINANCE) ALLOWED -> [] maskedBalance() (cfo, has ROLE_FINANCE) ALLOWED -> 1,204,993.22 @AuthorizeReturnObject: the check moves onto the returned object ---------------------------------------------------------------- returned instance -> com.ankurm.methodsec.Demo7DeniedHandling$Customer$$SpringCGLIB$$0 customer.getName() (no authority needed) ALLOWED -> alice customer.getEmail() (needs 'pii:read') DENIED -> AuthorizationDeniedException: Access Denied customer.getEmail() (has 'pii:read') ALLOWED -> alice@example.com Same thing without the annotation, via AuthorizationProxyFactory ---------------------------------------------------------------- raw.getEmail() (unproxied object) ALLOWED -> alice@example.com wrapped.getEmail() (proxied object) DENIED -> AuthorizationDeniedException: Access Denied