We have replaced JaasSecurityManager with our own version that synchronizes on principal-keyed locks. It looks safe enough, and performance is greatly improved. Its trivial code, but I can submit it if anyone wants it.
We discovered the same problem this week. In our case a login module blocked at the database by another transaction led to a system wide deadlock.
It looks like there was an attempt to fix this last year, but the fix was rolled back a few days later:
> Mon Sep 15 15:52:01 2003 UTC (5 months, 1 week ago) by starksm
> Move the synchronization on the isValid method to the authenticate call to
> improve concurrency to the cache validation.
Is another try at the fix likely in 3.2.x? In the meantime, be careful in your login modules.
It appears to us that the synchronization in JaasSecurityManager is capable of causing significant performance problems in JBoss 3.2.1. The isValid() method, which is called from everywhere to do authentication and check authorization, is synchronized, presumably to protect the security cache. Ultimately the isValid() call may result in a call to our login module, which typically does database work. While our login module is doing the database work (username/password lookup, roles etc) no other part of the system can make a call to isValid(). Scott? Anyone? does this make sense, or are we missing something more fundamental :)
Thanks for confirming the issue that we are seeing. I thought we might be going crazy there for a moment.
Warning: dont do what we did, it broke things badly, making it possible for identity switches to occur mid-flight. The problem is with the shared use of the CallbackHandler (SecurityAssociationHandler). JaasSecurityManager uses the same instance of the handler to transfer principal/credentials back and forth between incoming calls to authenticate and the configured login modules. At the very least, defaultLogin(principal, crendential) needs to be synchronized, unless JAASSecurityManager is changed to create a new instance of the CallbackHandler for each request.
Sorry, may be I missed something. Was this issue resolved (I did not manage to find this item <376687> in the list)?
In addition, I did not catch the idea of the following method (version 3.2.6)
/** Get the currently authenticated Subject in securityDomain.
@return The Subject for securityDomain if one exists, false otherwise.
public static Subject getActiveSubject(String securityDomain)
Subject subject = null;
Sorry, for stupid questions - where should I "dig"?
Nothing to do with the issue presented but we also had several performance problems with the login phase and we simply used 2 different approaches for the login strategy.
First login using standard user/password login with costly database lookup of credentials, principals etc.
In this login we generate a session id that is used to automatically lookup the cached logged credentials in another loginmodule for the rest of the client logins.
In this way we somehow overule the need to create a different login module for each login attempt.
Hope this helps.
The scalability of the JaasSecurityManager.isValid method is a known issue and has an existing sourceforge bug:
[ 974735 ] Slow performance of JaasSecurityManager
The getActiveSubject is useless and not part of any security interface contract.