Cache on a Datasource security-domain
plgregoire Jun 22, 2012 9:56 AMHi,
I have a standalone.xml of a JBoss AS 7.1.0 configured with a datasource and two security domain, one for the datasource (login-module=SecureIdentity) and another for our EJB/Webservices (login-module=Database). All configurations are above in this post. Everything works fine except that after few days of uptime and charge on my web services, each call to database begin to be slower and slower. We discovered that the cache on the Datasource security domain is the problem : the unique user we have (_username_) is put again and again in the cache and the accessQueue of the LIRS eviction policy grows again and again.
ConcurrentLinkedQueue<E>.size() line: 388 --> loop over millions/billions of entry BoundedConcurrentHashMap$LIRS<K,V>.onEntryHit(HashEntry<K,V>) line: 1065 BoundedConcurrentHashMap$Segment<K,V>.put(K, int, V, boolean) line: 1395 DefaultAuthenticationCacheFactory$1(BoundedConcurrentHashMap<K,V>).put(K, V) line: 1970 JBossCachedAuthenticationManager.updateCache(LoginContext, Subject, Principal, Object) line: 519 JBossCachedAuthenticationManager.proceedWithJaasLogin(Principal, Object, Subject) line: 401 JBossCachedAuthenticationManager.authenticate(Principal, Object, Subject) line: 371 JBossCachedAuthenticationManager.isValid(Principal, Object, Subject) line: 160 JBossSecuritySubjectFactory.createSubject(String) line: 88 NoTxConnectionManagerImpl(AbstractConnectionManager).getSubject() line: 689 NoTxConnectionManagerImpl(AbstractConnectionManager).allocateConnection(ManagedConnectionFactory, ConnectionRequestInfo) line: 463 WrapperDataSource.getConnection() line: 129 ...
We was wondering why the queue was never flushed and after investigation we see what happen:
1. In JBossCachedAuthenticationManager.isValid(), getCacheInfo() is called with the principal corresponding to our authenticated EJB user.
2. Since we are in the cache of our datasource security domain, the user is not found in the cache.
3. authenticate() is called and login is made using the SecureIdentityLoginModule.
4. The SecureIdentityLoginModule put in the current Subject the _username_ of our DB.
5. JBossCachedAuthenticationManager.updateCache() is called using our DB user as principal.
So the lookup in the cache is always made with a user of our EJB security domain and the put in the cache is always made with our single DB user. Since the BoundedConcurrentHashMap execute the eviction policy only when it get an entry hit on the getCacheInfo() and in our case we never get an entry hit, the accessQueue is never flushed.
Here are my questions :
a. Is it still a good practice to use a Security Domain on a datasource in Jboss 7 or should we always use a plain username/password in the security tag of the datasource?
b. Should we always disable the cache on a Security Domain using a login module of type SecureIdentity?
c. In all case, should I report the current behavior as a bug?
Thank you, here are our standalone.xml configurations:
<datasource jta="true" jndi-name="java:/myDS" pool-name="MySqlDS" enabled="true" use-java-context="true" use-ccm="true"> <connection-url>jdbc:mysql://localhost/db?autoReconnect=true</connection-url> <driver>mysql</driver> <pool> ... </pool> <security> <security-domain>MyDBDomain</security-domain> </security> <validation> ... </validation> </datasource> <security-domain name="MyDBDomain" cache-type="default"> <authentication> <login-module code="SecureIdentity" flag="required"> <module-option name="username" value="_username_"/> <module-option name="password" value="_encryptedPassword_"/> <module-option name="managedConnectionFactoryName" value="jboss.jca:name=myDS,service=LocalTxCM"/> </login-module> </authentication> </security-domain> <security-domain name="WebServiceDatabaseAuth" cache-type="default"> <authentication> <login-module code="Database" flag="sufficient"> <module-option name="dsJndiName" value="java:/myDS"/> <module-option name="principalsQuery" value="SELECT getPrincipalCredential(?);"/> <module-option name="rolesQuery" value="CALL GetPrincipalRoles(?);"/> <module-option name="hashAlgorithm" value="SHA-1"/> <module-option name="hashEncoding" value="HEX"/> <module-option name="unauthenticatedIdentity" value="anonymous"/> </login-module> </authentication> </security-domain>