6 Replies Latest reply on Jan 29, 2018 12:12 PM by Tom Stiemerling

    Reference Credential Store Programmatically

    Paul Carroll Newbie

      Hello, I am using Wildfly 11.0.0 and I have created a credential store with a couple of aliases.  One of the aliases is my database password and I reference it in the datasource subsystem in standalone.xml similar to the following:

       

      <security>
        <user-name>dbUsername</user-name>
        <credential-reference store="myCS" alias="datasourcePW"/>
      </security>
      

       

      I have some startup classes that I need to run as a specific user.  This user may not be the same for all deployments so I will obtain the username from a properties file but I would like to obtain the password from the credential store.  Is it possible to obtain the password from the credential store programmatically?  The following is the snippet of code from my startup class.

       

      final org.wildfly.security.auth.server.SecurityDomain securityDomain = org.wildfly.security.auth.server.SecurityDomain.getCurrent();
      final SecurityIdentity securityIdentity = securityDomain.authenticate( userNameFromPropFile, new PasswordGuessEvidence( passwordFromCredentialStore ) );
      Callable<Void> callable = () ->
      {
        startupMethod();
        return null;
      };
      securityIdentity.runAs( callable );
      
      
      

       

      Thank you

        • 1. Re: Reference Credential Store Programmatically
          gir489 Novice

          I think this is a bad idea, because you're storing the DB password in plain text on the disk for an attacker to find.

           

          Is there reason why you don't want to use a KeyStore?

          • 2. Re: Reference Credential Store Programmatically
            Paul Carroll Newbie

            I do not believe the DB password is stored in plain text.  It appears to be encrypted in a file on disk.  I used the following command to create the credential store.  Once the credential store was created, I added the datasource password.

             

            jboss-cli.bat --connect
            /subsystem=elytron/credential-store=myCS:add(location=myCS.storage, relative-to=jboss.server.data.dir, credential-reference={clear-text="myPassword"}, create=true)
            /subsystem=elytron/credential-store=myCS:add-alias(alias=datasourcePW, secret-value=myDBPassword)
            
            

            When I open the credential store file, it clearly appears to be encrypted.

            • 3. Re: Reference Credential Store Programmatically
              gir489 Novice

              Oh, I see. I misread datasourcePW as databasePW.

               

              store means keystore, as the file should just be a JKS. Try loading it with a KeyStore program like KeyStore explorer.

               

              If you're able to open it, then just use Oracle's KeyStore class to open and retrieve the credentials.

              • 4. Re: Reference Credential Store Programmatically
                Paul Carroll Newbie

                I found this code snippet at https://github.com/wildfly/wildfly/blob/master/testsuite/shared/src/main/java/org/wildfly/test/security/servlets/ReadCredentialServlet.java.

                The code below will allow me to obtain a password from a credential store.

                 

                import org.jboss.as.server.CurrentServiceContainer;
                import org.jboss.msc.service.ServiceContainer;
                import org.jboss.msc.service.ServiceController;
                import org.jboss.msc.service.ServiceName;
                import org.wildfly.security.credential.PasswordCredential;
                import org.wildfly.security.credential.store.CredentialStore;
                import org.wildfly.security.credential.store.CredentialStoreException;
                import org.wildfly.security.evidence.PasswordGuessEvidence;
                import org.wildfly.security.password.Password;
                import org.wildfly.security.password.interfaces.ClearPassword;
                
                
                ...
                private static final ServiceName SERVICE_NAME_CRED_STORE = ServiceName.of("org", "wildfly", "security", "credential-store");
                ...
                
                
                String credentialStore = "myCS";
                String alias = "datasourcepw";
                String clearPassword = null;
                ServiceContainer registry = CurrentServiceContainer.getServiceContainer();
                List<ServiceName> services = registry.getServiceNames();
                
                
                ServiceController<?> credStoreService = registry.getService(ServiceName.of(SERVICE_NAME_CRED_STORE, credentialStore));
                CredentialStore cs = (CredentialStore) credStoreService.getValue();
                
                
                try
                {
                  if( cs.exists( alias, PasswordCredential.class ) )
                  {
                    Password password = cs.retrieve( alias, PasswordCredential.class ).getPassword();
                    if( password instanceof ClearPassword )
                    {
                      clearPassword = new String( ((ClearPassword) password).getPassword() );
                      logger.debug( "CLEAR PASSWORD: " + clearPassword );
                    }
                  }
                }
                catch( CredentialStoreException | IllegalStateException e )
                {
                  System.out.println( "Unable to retrieve password  from credential store", e );
                }
                
                • 5. Re: Reference Credential Store Programmatically
                  Tom Stiemerling Newbie

                  I have basically the same question. Using the JBoss vault we are able to access passwords from the vault using the org.jboss.security.vault.SecurityVaultUtil class:

                   

                  if (SecurityVaultUtil.isVaultFormat(password)) {

                       decryptedStr = SecurityVaultUtil.getValueAsString(password);

                  } else {

                       decryptedStr = password;

                  }

                   

                  Is there anything provided in WildFly11 that does the same thing for a credential store - or do we have to go to the lengths above to access a credential store?

                  • 6. Re: Reference Credential Store Programmatically
                    Tom Stiemerling Newbie

                    ok, found code in the credential store source on github:

                     

                    wildfly-elytron/KeystorePasswordStoreTest.java at master · wildfly-security/wildfly-elytron · GitHub

                     

                    that allows us to access a store:

                     

                    Provider provider = new WildFlyElytronProvider();

                    Security.addProvider(provider);

                    CredentialStore store = CredentialStore.getInstance(KeyStoreCredentialStore.KEY_STORE_CREDENTIAL_STORE);

                    Map<String, String> attributes = new HashMap<>();

                    attributes.put("keyStoreType", "JCEKS");

                    attributes.put("location", "test.jceks");

                    CredentialSourceProtectionParameter protection = new CredentialSourceProtectionParameter(

                    IdentityCredentials.NONE.withCredential(new PasswordCredential(

                    ClearPassword.createRaw(ClearPassword.ALGORITHM_CLEAR, "password".toCharArray()))));

                    store.initialize(attributes, protection);

                    store.retrieve("alias", PasswordCredential.class);