2 Replies Latest reply on Sep 23, 2015 3:39 PM by plgregoire

    Cache on a Datasource security-domain

    plgregoire

      Hi,

       

      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>
      
      
        • 1. Re: Cache on a Datasource security-domain
          skerstetter

          I'm having this exact problem in an application that I am working on.  Did you find a resolution?  Was it enough to remove the 'cache-type="default"' from the db credentials security domain?  With enough concurrency, I get all my threads stacked up waiting to update this cache.

          • 2. Re: Cache on a Datasource security-domain
            plgregoire

            Yes it was enough! I run with the cache disabled since all these years and I never got this problem again.

             

            <security-domain name="MyDBDomain"> 

                 <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>