Add every example from the post, plus edge cases, to the companion repo
Full companion repo for the ankurm.com post "Spring Security Context Propagation: The Complete Guide" -- every code example the post discusses now has a corresponding runnable, verified demo (JDK 25, Spring Security 7.1.1, Spring Boot 4.1.1 dependency versions), not just the virtual-thread/structured-concurrency sections: - Demo1PlainThreadLocal: InheritableThreadLocal across thread models (no Spring) - Demo2AsyncVirtualThreads: @Async on a virtual-thread SimpleAsyncTaskExecutor (DelegatingSecurityContextExecutor vs ContextPropagatingTaskDecorator) - Demo3StructuredConcurrency: StructuredTaskScope.fork() propagation - Demo4ExecutorWrapping: DelegatingSecurityContextExecutorService/Executor/ AsyncTaskExecutor on a classic pooled platform-thread executor -- the post's "Using @Async" / "Using ExecutorService" / "Using CompletableFuture" sections - Demo5ReactiveContext: ReactiveSecurityContextHolder vs. ThreadLocal across a Reactor scheduler hop -- the post's WebFlux/getProfile() section - Demo6ScheduledSystemIdentity: DelegatingSecurityContextTaskScheduler's actual per-call capture semantics (confirmed via bytecode before writing the demo) and the createSystemContext() pattern -- the post's scheduled-tasks section - Demo7ServletFilterPersistence: SecurityContextHolderFilter (load-only) vs. SecurityContextPersistenceFilter (load+auto-save), against real filter instances and a real HttpSession -- the post's servlet-environment section - SecurityContextPropagationContractTest: 10 JUnit tests pinning the above as assertions instead of printed lines, including a TestSecurityContextHolder-based test reproducing the post's own "Testing Security Context Propagation" section Thirteen edge cases discovered along the way are indexed in docs/08 with links into the chapter that reproduces each one -- a reused pool worker NOT leaking under the Delegating* wrappers (unlike Demo1's InheritableThreadLocal), the common ForkJoinPool trap, why there's no DelegatingSecurityContextStructuredTaskScope and never will be, a real NullPointerException from Reactor's map() hit while writing the reactive test, per-call (not per-construction) context capture in DelegatingSecurityContextTaskScheduler, and the precise load-vs-save split between the two servlet filters, among others. docs/01-08 are numbered, cross-linked chapters with prev/next navigation; README indexes all demos, chapters, captured output, and the edge-case list. scripts/run-all.sh regenerates every docs/output/*.txt and the test suite output from one command.
This commit is contained in:
9
docs/output/demo4.txt
Normal file
9
docs/output/demo4.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
=== Demo 4: Executor/ExecutorService/AsyncTaskExecutor wrapping on a pooled platform thread ===
|
||||
A) raw ThreadPoolExecutor, no wrapper: NO AUTHENTICATION (lost)
|
||||
B) DelegatingSecurityContextExecutorService.execute(...): authenticated as bob
|
||||
B2) DelegatingSecurityContextExecutorService.submit(Callable): authenticated as bob
|
||||
EDGE) task 1 on possibly-reused worker: authenticated as carol-task1
|
||||
EDGE) task 2, same pool, different caller context: authenticated as dave-task2 <-- correct, NOT stale, unlike plain InheritableThreadLocal on a reused worker
|
||||
C) DelegatingSecurityContextExecutor + CompletableFuture.supplyAsync: authenticated as erin
|
||||
C2) default CompletableFuture executor (common ForkJoinPool), no wrapper: NO AUTHENTICATION (lost)
|
||||
D) DelegatingSecurityContextAsyncTaskExecutor wrapping ThreadPoolTaskExecutor: authenticated as grace
|
||||
Reference in New Issue
Block a user