Igor Kromin |   Consultant. Coder. Blogger. Tinkerer. Gamer.

I've been trying to figure out the Oracle CSF 11g documentation over the last couple of days without getting very far. The documentation is a bit incomplete and has errors in it (referencing classes that do not exist for example). So since I had to implement this for the project I am on, I had no choice by to figure it out myself.

What this example will demonstrate is how to use the credential store to store and retrieve a password for a given key in a given map.

First to get started, some JAR files from the Oracle Fusion Middleware is required. The easiest way is to get these is to install JDeveloper 11g. Below is a list of files needed to be on the classpath for the project (these are located in Middleware/oracle_common/modules):
  • oracle.idm_11.1.1/identitystore.jar
  • oracle.osdt_11.1.1/osdt_cert.jar
  • oracle.osdt_11.1.1/osdt_core.jar
  • oracle.osdt_11.1.1/osdt_xmlsec.jar
  • oracle.pki_11.1.1/oraclepki.jar
  • oracle.jps_11.1.1/jacc-spi.jar
  • oracle.jps_11.1.1/jps-api.jar
  • oracle.jps_11.1.1/jps-az-api.jar
  • oracle.jps_11.1.1/jps-az-common.jar
  • oracle.jps_11.1.1/jps-az-management.jar
  • oracle.jps_11.1.1/jps-az-rt.jar
  • oracle.jps_11.1.1/jps-ee.jar
  • oracle.jps_11.1.1/jps-common.jar
  • oracle.jps_11.1.1/jps-internal.jar
  • oracle.jps_11.1.1/jps-pep.jar
  • oracle.jps_11.1.1/jps-se.jar
  • oracle.jps_11.1.1/jps-unsupported-api.jar




Next thing to do is set the Java options for running the compiled code like this:
-Doracle.security.jps.config=./jps-config-jse.xml -Djava.security.debug=off


The debug setting can be set to 'all' to see exactly what CSF is doing, that tends to produce quite a lot of output, so I've turned it off.

Now the jps-config-jse.xml file needs to be created. The official documentation does not provide a full example of this, but there is an example of this file in the JDeveloper directories, I used that to create the file below.
<jpsConfig xmlns="http://xmlns.oracle.com/oracleas/schema/11/jps-config-11_1.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/oracleas/schema/11/jps-config-11_1.xsd jps-config-11_1.xsd"
schema-major-version="11"
schema-minor-version="1">
<property name="oracle.security.jps.jaas.mode" value="off"/>
<serviceProviders>
<serviceProvider type="CREDENTIAL_STORE" name="credstoressp" class="oracle.security.jps.internal.credstore.ssp.SspCredentialStoreProvider">
<description>SecretStore-based CSF provider</description>
</serviceProvider>
<serviceProvider type="POLICY_STORE" name="policystore.xml.provider" class="oracle.security.jps.internal.policystore.xml.XmlPolicyStoreProvider">
<description>XML-based PolicyStore Provider</description>
</serviceProvider>
</serviceProviders>
<serviceInstances>
<serviceInstance name="credstore" provider="credstoressp" location="./">
<description>File Based Credential Store Service Instance</description>
</serviceInstance>
<serviceInstance name="policystore.xml" provider="policystore.xml.provider" location="./system-jazn-data.xml">
<description>File Based Policy Store Service Instance</description>
</serviceInstance>
</serviceInstances>
<jpsContexts default="default">
<jpsContext name="default">
<serviceInstanceRef ref="credstore"/>
<serviceInstanceRef ref="policystore.xml"/>
</jpsContext>
</jpsContexts>
</jpsConfig>


What the file does is tell CSF to create a credential store and a policy store. The policy store is not actually used, but the code was throwing exceptions without it so I added it in. The location of the wallet file will be in the same directory as the config file with the above setup.

The file above also references system-jazn-data.xml, so that needs to be created. There is no setup required for our purposes in that file, so it's contents are just this:
<jazn-data/>


Now that the config is done, I used the example CsfUtil class and modified it to store one single password credential in the map called 'pc_map' for the key called 'pc_key'. The code is really quite simple.
import java.security.AccessController;
import java.security.PrivilegedAction;
import oracle.security.jps.JpsException;
import oracle.security.jps.service.credstore.CredentialAlreadyExistsException;
import oracle.security.jps.service.credstore.CredentialFactory;
import oracle.security.jps.service.credstore.CredentialStore;
import oracle.security.jps.service.credstore.PasswordCredential;
public class CsfUtil {
final CredentialStore store;
public CsfUtil(CredentialStore store) {
super();
this.store = store;
}
private void doOperation() {
try {
PasswordCredential pc = null;
try {
pc = (PasswordCredential)store.getCredential("pc_map", "pc_key");
if (pc == null) {
// key not found, create one
pc = CredentialFactory.newPasswordCredential("jdoe",
"password".toCharArray());
// this call requires write privilege
store.setCredential("pc_map", "pc_key", pc);
System.out.print("Created ");
}
else {
System.out.print("Found ");
}
System.out.println("password credential: Name=" + pc.getName() +
",Password=" +
new String(pc.getPassword()));
} catch (CredentialAlreadyExistsException e) {
// ignore since credential already exists.
System.out.println("Credential already exists for <pc_map, pc_key>: " + pc.getName() + ":" +
new String(pc.getPassword()));
}
} catch (JpsException e) {
e.printStackTrace();
}
}
/*
* Since this method performs a privileged operation, only current class or
* jar containing this class needs CredentialAccessPermission
*/
public void doPrivilegedCredOperation() {
AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
doOperation();
return "done";
}
});
}
}


I created a separate class as per the official documentation to call the utility code. This class was as follows:
import oracle.security.jps.JpsContext;
import oracle.security.jps.JpsContextFactory;
import oracle.security.jps.JpsException;
import oracle.security.jps.service.credstore.CredentialStore;
public class Environment {
// set the OPSS policy provider explicitly, as required in a Java SE application
static {
java.security.Policy.setPolicy(new oracle.security.jps.internal.policystore.JavaPolicyProvider());
}
public static void main(String[] a) {
JpsContextFactory ctxFactory;
try {
ctxFactory = JpsContextFactory.getContextFactory();
JpsContext ctx = ctxFactory.getContext();
CredentialStore store = ctx.getServiceInstance(CredentialStore.class);
CsfUtil csf = new CsfUtil(store);
csf.doPrivilegedCredOperation();
} catch (JpsException e) {
e.printStackTrace();
}
}
}


That's it! First time this code runs it creates the cwallet.sso file, which is the Oracle Wallet. The second time the code is run, it fetches the password out of the wallet.

-i

A quick disclaimer...

Although I put in a great effort into researching all the topics I cover, mistakes can happen. Use of any information from my blog posts should be at own risk and I do not hold any liability towards any information misuse or damages caused by following any of my posts.

All content and opinions expressed on this Blog are my own and do not represent the opinions of my employer (Oracle). Use of any information contained in this blog post/article is subject to this disclaimer.
Hi! You can search my blog here ⤵
NOTE: (2022) This Blog is no longer maintained and I will not be answering any emails or comments.

I am now focusing on Atari Gamer.