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

NOTE: This article is 3 years or older so its information may no longer be relevant. Read on at your own discretion! Comments for this article have automatically been locked, refer to the FAQ for more details.
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

Skip down to comments...
Hope you found this post useful...

...so please read on! I love writing articles that provide beneficial information, tips and examples to my readers. All information on my blog is provided free of charge and I encourage you to share it as you wish. There is a small favour I ask in return however - engage in comments below, provide feedback, and if you see mistakes let me know.

If you want to show additional support and help me pay for web hosting and domain name registration, donations, no matter how small, are always welcome!

Use of any information contained in this blog post/article is subject to this disclaimer.
 
comments powered by Disqus
Other posts you may like...