Hello CAS Community,
I've discovered and fixed an LDAP connection leak issue affecting CAS 7.3.x and master that occurs during Spring @RefreshScope refresh cycles (triggered via /actuator/refresh endpoint).
Problem:
When @RefreshScope bean recreation occurs, LdapAuthenticationHandler instances wrapped in BeanContainer are not properly destroyed. Spring only manages the BeanContainer lifecycle, not the handlers inside it. This prevents LdapAuthenticationHandler.destroy() from being called, leaving LDAP connection pools open and leaking threads with each refresh cycle.
Validation:
I confirmed this using VisualVM thread profiling:
-
Before fix: Thread count increases with each /actuator/refresh call, and live thread viewer shows multiple ldap threads.
After fix: Thread count remains flat, live thread viewer does not show multiple, concurrent ldap threads - connections properly closed
Solution:
LdapAuthenticationPlanConfiguration now implements DisposableBean to explicitly track and destroy LDAP handlers during bean destruction. This follows the same pattern already used by LdapHttpSecurityCasWebSecurityConfigurer in the same file (line 139).
Pull Requests:
Bot Auto-Closed:
Both PRs were auto-closed by the bot requesting unit tests. However, this is a Spring lifecycle management issue that's difficult to test in isolation because:
- Unit tests don't exercise Spring Cloud's @RefreshScope proxy destruction behavior
- The issue requires actual LDAP connection pool behavior over multiple refresh cycles
- The existing precedent (LdapHttpSecurityCasWebSecurityConfigurer.destroy()) in the same file also has no dedicated lifecycle tests
Request for Feedback:
We'd appreciate maintainer review of these PRs. Happy to discuss the testing approach or make any changes needed. If there's a practical way to add lifecycle tests for @RefreshScope behavior, we're open to implementing that.
Thank you for your consideration.