Friday, October 2, 2009

Oracle Entitlements Server 10gR3 and Coherence 3.5 Integration

The following is intended to show the current integration points around Coherence and the Oracle Entitlements Server (OES) product. The will show how a Coherence application can be configured to call out to an OES Security Module for an entitlement decision by the OES engine. The granularity of a resource provided by Coherence is to the cache-name which can be used to determine if a specific authenticated user has access to a named cache in the grid.

The value of this solution is that someone could enforce distributed policies on a named cache in the data grid so that not just “anyone” can access their data. The policies would be centrally configured and then automatically distributed to all of the endpoints (OES SSMs) for enforcement at the client level. This would eliminate the need to update the client side Coherence permissions.xml file on each individual client which could be a large maintenance task. If someone is interested in securing access to a named cache in Coherence this can achieved by following the general guide at Coherence Security Framework and implementing the com.tangosol.net.security.AccessController interface to call out to an OES SSM (Security Service Module). In this case the RMI-SSM is best used for performance reasons.

The AccessController class can be generic in nature and the code provided later on could be easily reused. However the configuration for the Coherence side would be specific to the SSM, its location, and other configuration variables for OES.


Currently only the name of the cache is exposed as a resource that one can write policies on from the Coherence ClusterPermission object. Coherence does not currently give you the name of the Object key if one has to goto that level.


“How-To” secure a Coherence Application with OES SSM:

It is assumed that one has already installed and configured the OES product (OES Admin Server and OES SSMs) and Oracle Coherence product prior to this.   NOTE:  A Jdeveloper sample project is available upon request. :)

OES Setup:

1. The following step only needs to be done once per machine. The reason is that the OES 10gR3 installation kit does not do this out-of-the-box during installation. Create the rmi-ssm directory structure by running the OES_HOME\ales32-ssm\webservice-ssm\adm\rmi-adm\create_rmi_ssm.(bat/sh) utility. This will create an OES_HOME\ales32-ssm\rmi-ssm directory with all of the material needed for this SSM.

2. Create an instance of an RMI-SSM by running the OES_HOME\ales32-ssm\rmi-ssm\adm\ConfigTool.(bat/sh) utility which use a configuration file to automatically create the SSM instance and configure this in the OES Admin Server which has the necessary policies. A sample “myssm_config.properties” file is located in the JDeveloper Project under the “OES_RMI_Setup” directory.

3. Build the Username Identity Asserter. This is used in this example to assert the identity passed in from the Coherence application as valid. It is assumed that the authentication done on the client side is valid and OES is being strictly used as an authorization engine. Follow the instructions listed in the OES_HOME\ales32-ssm\rmi-ssm\examples\SampleProviders\UsernameAsserter directory. You will need to copy this JAR file to the Admin Server side and the RMI-SSM instance.

4. Configure the Username Identity Asserter in the “CoherenceSSM” entry on the OES Admin Server (which was just created in step 2). Login to: https://localhost:7010/asi (default user/password is: admin/password) and look on the left-hand side under Security Configurations -> Service Control Managers -> adminconfig -> CoherenceSSM -> Authentication Providers to create a new instance of “Username Identity Asserter”. It will look like the following:



5. OES does need to know what the name of the user is since policies are written based on a Subject. For this example, we can enter the names of our users in the “asi” identity directory since the RMI-SSM points to this. In this case it will be the user names created in the keystore for the Coherence side of things (steve, larry, and bill are the sample users).

6. Create a sample group (Coherence_Group), put the user names from the “asi” identity directory into this group, and later (step 8) create a policy on the “testCache” resource which only allows members of this group access. This is what it would look like in the Entitlements Administration Console (https://localhost:7010/entitlementsadministration):



7. Create the resource tree under the binding name of the “CoherenceSSM” you just created. For example it would look like this: CoherenceSSM/testCache and CoherenceSSM/__ASTR_ (this is the literal value for the “*” that can be passed in from Coherence as well).

8. Create the Authorization Policy on both of those resources (testCache and __ASTR_). For this example I allowed the “Coherence_Group” access to these resources only. This group contained “steve”, “larry”, and “bill”. This is what the authorization policy will look like on the CoherenceSSM/testCache:



9. Copy the “pdpproxy” directory (OES_HOME\ales32-ssm\rmi-ssm\instance\CoherenceSSM\pdpproxy) to a separate location since the Coherence “client” application will need access to it (or you can modify the command line parameters to point to this). In this case it is part of the JDeveloper project already. You may need to modify the pdpproxy\PDPClientConfiguration.properties to make sure the names in this file match your environment.

10. Modify the “security.properties” which is also on the Coherence client side (in the JDeveloper project) so that the name matches what you have configured. In this case it would be “CoherenceSSM”.


Coherence Setup:

1. Create a sample Coherence application. (This is already in the JDeveloper project and called “com.oracle.oes.coherence.client.OESCoherenceClient”.)

2. Add a runAs() method around what you are trying to secure. Example:
PrivilegedAction action = new PrivilegedAction() {

public Object run() {

// All processing here is with access rights assigned to the Subject

CacheFactory.ensureCluster();

// create or get a named cache called mycache

NamedCache myCache = CacheFactory.getCache("testCache");

// put key, value pair into the cache.

myCache.put("key1", "Hello world");

System.out.println("Client Code: Inside runAs() end");

return null;

}

};


3. Modify the run configuration in JDeveloper to include the coherence configuration and the OES configuration. An example of this is located in the JDeveloper project (in the *.jpr file) and look for the “Security_Run_Storage” section.

4. Make sure there is a “-Djava.security.auth.login.config=” flag which points to a JAAS configuration file. This configuration file contains the keystore used in this example for Authentication from the Coherence application. In the JDeveloper project look at the “Coherence_Keystore.conf” file and make sure that the information in this file points to the correct location of the Keystore.jks file (this will be created in step6).

5. Modify the tangosol-coherence.xml file and make sure it points to the AccessController class which contains the code to call the OES RMI-SSM. For example:

com.oracle.oes.coherence.impl.OES_AccessController

……..

6. Create a keystore with some users configured. You can run the following set of commands to create the keystore (assuming you have Java 1.5 executable set in your environment):

keytool -genkey -v -keystore ./keystore.jks -storepass password -alias steve -keypass password -dname CN=steve,OU=MyUnit

keytool -genkey -v -keystore ./keystore.jks -storepass password -alias larry -keypass password -dname CN=larry,OU=MyUnit

keytool -genkey -v -keystore ./keystore.jks -storepass password -alias bill -keypass password -dname CN=bill,OU=MyUnit

keytool -genkey -v -keystore ./keystore.jks -storepass password -alias dave -keypass password -dname CN=dave,OU=MyUnit


Testing:

1. Start the RMI-SSM. For example: “OES_HOME\ales32-ssm\rmi- ssm\instance\CoherenceSSM\bin\WLESrmi.bat console” and make sure this starts successfully.

2. Start JDeveloper, import the JDeveloper project, and modify the classpaths to point to the correct installation location of OES and Coherence on your machine.

3. Right click and run the “com.oracle.oes.coherence.client.OESCoherenceClient”. If everything is configured correctly this will invoke the AccessController class with the authenticated user “steve” (“com.oracle.oes.coherence.impl.OES_AccessController”), contact the RMI-SSM (which is already running), and render an authorization decision. If the client is “hanging” at initializing the Security Services Framework, check that the PDPClientConfiguration.properties is configured on the command line of the Coherence client and also enable debugging in the AccessController and OES_Authorization_Impl code by setting the DEBUG value to true. This will be the output within JDeveloper:

Oracle Coherence Version 3.4.1/407

Grid Edition: Development mode

Copyright (c) 2000-2008 Oracle. All rights reserved.

Client Code: Inside runAs() begin: security action

2009-02-04 11:33:53.926/3.345 Oracle Coherence GE 3.4.1/407 (thread=Cluster, member=n/a): Service Cluster joined the cluster with senior service member n/a

2009-02-04 11:33:57.176/6.595 Oracle Coherence GE 3.4.1/407 (thread=Cluster, member=n/a): Created a new cluster "cluster:0x30D1" with Member(Id=1, Timestamp=2009-02-04 11:33:53.66, Address=169.254.25.129:8088, MachineId=26952, Location=machine:SPOZ03,process:4724, Edition=Grid Edition, Mode=Development, CpuCount=2, SocketCount=1) UID=0xA9FE19810000011F422373FC69481F98

2009-02-04 11:33:57.222/6.641 Oracle Coherence GE 3.4.1/407 (thread=Main Thread, member=1): Loaded cache configuration from file "C:\spoz\coherence\OES_COH\coherence-cache-config.xml"

Subject is:[CN=steve, OU=MyUnit]

clusterPermission actions are:join, and ServiceName is:DistributedCache

(com.tangosol.net.ClusterPermission service=DistributedCache,cache=* join)

Cache Name is:*

accessResult is:true for

subject:[CN=steve, OU=MyUnit]

resource:*

2009-02-04 11:33:57.910/7.329 Oracle Coherence GE 3.4.1/407 (thread=DistributedCache, member=1): Service DistributedCache joined the cluster with senior service member 1

Subject is:[CN=steve, OU=MyUnit]

clusterPermission actions are:join, and ServiceName is:DistributedCache

(com.tangosol.net.ClusterPermission service=DistributedCache,cache=testCache join)

Cache Name is:testCache

accessResult is:true for

subject:[CN=steve, OU=MyUnit]

resource:testCache

Client Code: Inside runAs() end

Value in cache is Hello world

Process exited with exit code 0.

4. Change the code and pass in the user “dave” who is in the keystore however not part of the Coherence_Group for the entitlements policy as shown in the earlier screenshot. When the client is run one will see the following messages in JDeveloper and the AccessControlException is thrown as per the Coherence checkPermission API:

accessResult is:false for

subject:[CN=dave, OU=MyUnit]

resource:*

Deny and throw exception

Exception in thread "Main Thread" java.security.AccessControlException: Insufficient rights to perform the operation (com.tangosol.net.ClusterPermission service=DistributedCache,cache=* join) for Subject:[CN=dave, OU=MyUnit]

5. You can enable debugging on the RMI SSM instance to determine why access was or was not granted for the named cache.


Coherence Client Code Example:

package com.oracle.oes.coherence.client;

import com.tangosol.net.CacheFactory;
import com.tangosol.net.NamedCache;
import com.tangosol.net.security.Security;
import java.security.PrivilegedAction;
import javax.security.auth.Subject;
import com.oracle.oes.coherence.impl.OES_AccessController;

import java.security.AccessControlException;

public class OESCoherenceClient {
public OESCoherenceClient() {
}

public static void main(String[] args) {


if (args.length != 1) {
System.out.println("Please supply a user name");
System.exit(0);
}

String sName = args[0].toString();

char[] acPassword = null;
acPassword = "password".toCharArray();

System.out.println("*** Starting Client ***");
// It is assume that the main application has the username/password already from the "client"
Subject subject = Security.login(sName, acPassword);

// The coherence client only has to pass in their credentials and configure the tangosol-coherence.xml
// file to use the com.oracle.oes.coherence.impl.OES_AccessController class in the class-name of the
// access-controller section of that XML file. Each client does not need to know or reimplement the
// OES code. They would just need to wrap their coherence calls inside a runAs() method as per
// normal JAAS security.

// Do something with the cache where an entitlement decision is rendered by OES based on the
// subject, resource (testCache here), and the action/permission.
PrivilegedAction action = new PrivilegedAction() {
public Object run() {
// All processing here is taking place with access rights assigned to the corresponding Subject
System.out.println("Client Code: Inside runAs() begin: security action");
CacheFactory.ensureCluster();

// create or get a named cache called mycache
NamedCache myCache = CacheFactory.getCache("testCache");
// put key, value pair into the cache.
myCache.put("key1", "Hello world");
System.out.println("Client Code: Inside runAs() end");
return null;
}
};
Security.runAs(subject, action);

// Access the cache since it is already secured above for the same named cache
NamedCache myCache = CacheFactory.getCache("testCache");
System.out.println("Value in cache is " + myCache.get("key1"));

}
}


Example of AccessController Implementation for Integration with OES:


package com.oracle.oes.coherence.impl;

import com.bea.security.*;

import com.tangosol.net.CacheFactory;
import com.tangosol.net.ClusterPermission;

import com.tangosol.run.xml.SimpleParser;

import com.tangosol.run.xml.XmlDocument;
import com.tangosol.run.xml.XmlElement;
import com.tangosol.run.xml.XmlHelper;
import com.tangosol.util.LiteSet;
import com.tangosol.util.Resources;
import com.tangosol.util.SafeHashMap;
import java.io.*;
import java.net.URL;
import java.security.*;
import java.security.cert.CertPath;
import java.security.cert.X509Certificate;

import java.util.*;
import javax.security.auth.Subject;
import javax.security.auth.x500.X500Principal;
import javax.security.auth.x500.X500PrivateCredential;


public class OES_AccessController implements com.tangosol.net.security.AccessController {

private boolean DEBUG = false;
private boolean nonOESDebug = false;
private java.security.KeyStore m_store;
private XmlElement m_xmlPermits;
private Map m_mapPublicKey;
public static final String PROPERTY_CONFIG = "tangosol.security.config";
public static final String KEYSTORE_TYPE;
public static final String SIGNATURE_ALGORITHM;
public static final Signature SIGNATURE_ENGINE;
public static final String BOUND_SSM_NAME = "CoherenceSSM/";

// OES
private OES_Authorization_Impl oesEng = new OES_Authorization_Impl();
private SecurityRuntime rt = null;
private PolicyDomain pd = null;
private AuthenticationService atnSvc = null;
private AuthorizationService atzSvc = null;

private void debugPrintPrivate (String s) {
if (nonOESDebug) System.out.println(s);
}

private void debugPrint (String s) {
if (DEBUG) System.out.println(s);
}

public OES_AccessController(File fileKeyStore, File filePermits)
throws IOException, AccessControlException
{
System.out.println("************************ IN Access Controller************");

m_mapPublicKey = new SafeHashMap();
if(!filePermits.exists() || !filePermits.canRead())
throw new IOException("Permission file is not accessible: " + filePermits.getAbsolutePath());
try
{
KeyStore store = KeyStore.getInstance(KEYSTORE_TYPE);
store.load(new FileInputStream(fileKeyStore), null);
m_store = store;
}
catch(Exception e)
{
System.out.println("Failed to load keystore: " + fileKeyStore.getAbsolutePath()+" exception:"+e.toString());
}
try
{
m_xmlPermits = (new SimpleParser()).parseXml(new FileInputStream(filePermits));
}
catch(Exception e)
{
System.out.println( "Failed to load permissions: " + filePermits.getAbsolutePath()+" exception:"+e.toString());
}

//
// Setup the services which call the OES SSM (PDP) and returns results to this Java class for enforcement (PEP)
// This will use the configuration file specified in the -Dpdp.configuration.properties.location=
// flag set on the coherence client...
//

String pdname = oesEng.tryGetPolicyDomainName();
System.out.println("--> pdname returned from the security.properties file is:"+pdname);

rt = oesEng.initializeSSM(pdname);
if (rt == null) {
System.out.println("Failed to initialize the setup to the OES SSM");
System.exit(-1);
}

// Fetch our policy domain from the runtime
pd = oesEng.tryGetPolicyDomain(rt, pdname);
if (pd == null) {
System.out.println("Failed to get the policy domain "+pdname+" for the OES SSM");
System.exit(-2);
}

// Get the authentication service from the policy domain so that the identity (subject passed here)
// can be asserted with the sample "User Name" Identity Asserter. OES will assume that authentication
// has already taken place successfully.
atnSvc = oesEng.tryGetAuthenticationService(pd);
if (atnSvc == null) {
System.out.println("Failed to get the Authentication service for the OES SSM");
System.exit(-3);
}

// Get the authorization service from the policy domain
atzSvc = oesEng.tryGetAuthorizationService(pd);
if (atzSvc == null) {
System.out.println("Failed to get the Authorization service for the OES SSM");
System.exit(-4);
}

}


/**
* The checkPermission API is the main method exposed by Coherence 3.4 where OES can plug-in and render
* a decision (grant/deny) based on the subject, action, resource passed in. The accessResult value is
* what is returned from the OES engine. If a deny is returned, then an exception is thrown as per the
* Coherence API documentation. See:
* http://download.oracle.com/otn_hosted_doc/coherence/340/com/tangosol/net/security/AccessController.html
*/
public void checkPermission(ClusterPermission clusterPermission,
Subject subject) {
// This same method can be called multiple times from a Coherence client. For example:
// joining the cluster, try to join a cache, etc...
// The current permissions from Coherence are: ALL, CREATE, DESTROY, JOIN, NONE
// Currently the most granular information one can get from Coherence is the name of the
// cache and not the actual object. See:
// http://download.oracle.com/otn_hosted_doc/coherence/340/com/tangosol/net/ClusterPermission.html

debugPrint("Subject is:"+subject.getPrincipals());
String actionATZ = clusterPermission.getActions();

debugPrint("clusterPermission actions are:"+actionATZ+", and ServiceName is:"+clusterPermission.getServiceName());
debugPrint(clusterPermission.toString());

// Get the actual name of the cache to pass to OES as the resource
String cacheNameATZ = clusterPermission.getName();
int cachePos = cacheNameATZ.indexOf("cache=");
cacheNameATZ = cacheNameATZ.substring(cachePos+6);
debugPrint("Cache Name is:"+cacheNameATZ);

// How should we best handle the "*" as a resource? This can either be added as a resource
// in OES or it can be ignored if desired
//if (cacheNameATZ.equals("*")) {
// debugPrint("Cache is actually a * here... ");
//}

// Start authentication which will assert the identity passed in. The Identity Asserter configured in
// OES for this RMI-SSM will let all identities passed since we are relying on the calling application
// to have been authenticated by some means (keystore, OAM, etc). OES needs some identity in which
// entitlements policies can be written
AuthenticIdentity ident = oesEng.tryAuthenticate(atnSvc, subject);
if (ident == null) {
System.out.println("Failed to authenticate the identiy within the OES SSM");
System.exit(-5);
}

HashMapContext appContext = new HashMapContext();
RuntimeResource resource = new RuntimeResource(BOUND_SSM_NAME+cacheNameATZ, "exampleResource");
RuntimeAction action = new RuntimeAction(actionATZ, "exampleAction");

// Call the OES authorization engine with the identity, resource, action and any hashmap context needed
AccessResult accessResult = oesEng.tryAuthorize(atzSvc, ident, resource, action, appContext);
System.out.println("accessResult is:"+accessResult.isAllowed()+" for\n\t subject:"+subject.getPrincipals()+"\n\t resource:"+resource);

// if the result is a DENY throw an exception. Otherwise it is a grant and do nothing since this is a void method...
if (!accessResult.isAllowed()) {
System.out.println("Deny and throw exception");
throw new AccessControlException("Insufficient rights to perform the operation "+clusterPermission+" for Subject:"+subject.getPrincipals());
} // of if

} // of checkPermissions


//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////

/**
/* All helper methods for this AccessController to do the work of encrypt and decrypt
* information from the keystore where the identity and passwords are stored. This is essentially
* what the DefaultController does in Coherence. There is no OES code from this point forward.
*/
public SignedObject encrypt(Object o, Subject subjEncryptor)
throws IOException, GeneralSecurityException
{

Set setPrivateCreds = subjEncryptor.getPrivateCredentials();
if(setPrivateCreds == null)
throw new GeneralSecurityException("Subject without private credentials");
for(Iterator iter = setPrivateCreds.iterator(); iter.hasNext();)
{
Object oCred = iter.next();
PrivateKey keyPrivate = null;
if(oCred instanceof PrivateKey)
keyPrivate = (PrivateKey)oCred;
else
if(oCred instanceof X500PrivateCredential)
keyPrivate = ((X500PrivateCredential)oCred).getPrivateKey();
if(keyPrivate != null)
return encrypt((Serializable)o, keyPrivate);
}

throw new GeneralSecurityException("Not sufficient credentials");
}

public Object decrypt(SignedObject so, Subject subjEncryptor,
Subject subjDecryptor) throws ClassNotFoundException, IOException, GeneralSecurityException {
debugPrintPrivate("In decrypt for my AccessController class");
PublicKey keyPublic;
Iterator iter;

keyPublic = (PublicKey)m_mapPublicKey.get(subjEncryptor);
if(keyPublic != null)
return decrypt(so, keyPublic);
Set setKeys = null;
if(subjDecryptor != null)
{
Set setDecryptorCreds = subjDecryptor.getPublicCredentials();
if(setDecryptorCreds != null && equalsMostly(subjDecryptor, subjEncryptor))
setKeys = extractPublicKeys(setDecryptorCreds);
}
if(setKeys == null)
setKeys = findPublicKeys(subjEncryptor);
iter = setKeys.iterator();
debugPrintPrivate("about to loop...");
do {
if(!iter.hasNext()) {
break; /* Loop/switch isn't completed */
} else {
keyPublic = (PublicKey)iter.next();
Object o;
o = decrypt(so, keyPublic);
m_mapPublicKey.put(subjEncryptor, keyPublic);
return o;
}
// throw new GeneralSecurityException("Failed in looping for credentials");
} while (true);

throw new GeneralSecurityException("Failed to match credentials for " + subjEncryptor);
}

protected SignedObject encrypt(Serializable o, PrivateKey keyPrivate)
throws IOException, GeneralSecurityException
{
return new SignedObject(o, keyPrivate, SIGNATURE_ENGINE);
}

protected Object decrypt(SignedObject so, PublicKey keyPublic)
throws ClassNotFoundException, IOException, GeneralSecurityException
{
if(so.verify(keyPublic, SIGNATURE_ENGINE))
return so.getObject();
else
throw new SignatureException("Invalid signature");
}

protected boolean equalsMostly(Subject subject1, Subject subject2)
{
debugPrintPrivate("In equalsMostly... hardcode since this equals() method listed doesn't resolve to anything in public Coherence docs");
//return equals(subject1.getPrincipals(), subject2.getPrincipals()) && equals(subject1.getPublicCredentials(), subject2.getPublicCredentials());
return true;
}

protected Set extractPublicKeys(Set setPubCreds)
{
Set setCerts = extractCertificates(setPubCreds);
Set setKeys = new LiteSet();
Certificate cert;
for(Iterator iter = setCerts.iterator(); iter.hasNext(); setKeys.add(cert.getPublicKey()))
cert = (Certificate)iter.next();

return setKeys;
}

protected Set extractCertificates(Set setPubCreds)
{
Set setCerts = new LiteSet();
Iterator iter = setPubCreds.iterator();
do
{
if(!iter.hasNext())
break;
Object oCred = iter.next();
if(oCred instanceof CertPath)
{
CertPath certPath = (CertPath)oCred;
List listCert = certPath.getCertificates();
if(!listCert.isEmpty())
setCerts.add(listCert.get(0));
} else
if(oCred instanceof Certificate)
{
Certificate cert = (Certificate)oCred;
setCerts.add(cert);
} else
if(oCred instanceof Certificate[])
{
Certificate acert[] = (Certificate[])oCred;
if(acert.length > 0)
setCerts.add(acert[0]);
} else
{
CacheFactory.log("Unsupported credentials: " + oCred.getClass(), 2);
}
} while(true);
return setCerts;
}

protected Set findPublicKeys(Subject subject)
throws GeneralSecurityException
{
java.security.KeyStore store = m_store;
Set setCerts = extractCertificates(subject.getPublicCredentials());
Set setPpals = new LiteSet();
Set setKeys = new LiteSet();
Iterator iter = setCerts.iterator();
do
{
if(!iter.hasNext())
break;
java.security.cert.Certificate cert = (java.security.cert.Certificate)iter.next();
if(store.getCertificateAlias(cert) != null && (cert instanceof X509Certificate))
{
X509Certificate certX509 = (X509Certificate)cert;
setPpals.add(new X500Principal(certX509.getIssuerDN().getName()));
setKeys.add(cert.getPublicKey());
}
} while(true);
if(!setPpals.containsAll(subject.getPrincipals()))
{
CacheFactory.log("Unable to verify the Principal set: " + subject.getPrincipals(), 2);
setKeys.clear();
}
return setKeys;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////

static
{
String sConfig = System.getProperty("tangosol.security.config");
XmlDocument xml = null;
String sKeystoreType = "JKS";
String sAlgorithm = "SHA1withDSA";
if(sConfig != null && sConfig.length() > 0)
{
URL url = Resources.findResource(sConfig, null);
Throwable e = null;
if(url != null)
try
{
xml = XmlHelper.loadXml(url.openStream());
}
catch(Throwable t)
{
e = t;
}
if(xml == null)
{
System.out.println("Unable to load DefaultController configuration file \"" + sConfig + "\";");
if(e != null)
System.out.println("e is:"+e);
System.out.println("Using default configuration.");
}
}
try
{
if(xml == null)
xml = XmlHelper.loadXml(com.tangosol.net.security.DefaultController.class, "ISO-8859-1");
sKeystoreType = xml.getSafeElement("keystore-type").getString(sKeystoreType);
sAlgorithm = xml.getSafeElement("signature-algorithm").getString(sAlgorithm);
}
catch(Throwable e) {System.out.println("In throwable for static?"); }
Signature engine;
try
{
engine = Signature.getInstance(sAlgorithm);
}
catch(Exception e)
{
throw new ExceptionInInitializerError(e);
}
KEYSTORE_TYPE = sKeystoreType;
SIGNATURE_ALGORITHM = sAlgorithm;
SIGNATURE_ENGINE = engine;
}

}


OES Authorization Client Code:


package com.oracle.oes.coherence.impl;

import com.bea.security.*;

import java.io.*;

import java.util.Enumeration;
import java.util.Properties;

import javax.security.auth.Subject;

/**
* This class does the work of connecting to the OES SSM and providing the Coherence Client
* (in the checkPermissions method) an easy way to call the isAccessAllowed API from OES.
*/
public class OES_Authorization_Impl {

public OES_Authorization_Impl() {
}

private boolean DEBUG = false;

// To enable quick performance stats on ATZ calls for a maximum looping number
// disable debug on the RMI-SSM and this will be in sub-millisecond time after the
// first ATZ call.
private boolean QUICK_PERF = false;
private int MAX_LOOP = 100;

// Default policy domain name however it will read the security.properties file in
// the working directory for the actual name.
public static final String DEFAULT_CONFIGURATION_ID = "asiadmin";

// Token type expected by the User Name Identity Asserter configured in the OES SSM
private static String USERID_TOKEN_TYPE = "USERID_TOKEN";

protected String tryGetPolicyDomainName() {
// Check for the standard system property
String configId = System.getProperty("wles.realm");

Properties props = new Properties();
if (configId == null) {
try {
props.load(new BufferedInputStream(new FileInputStream("security.properties")));

String realmName = props.getProperty("wles.realm");
if (realmName != null) {
configId = realmName;
} else {
String realm1Name = props.getProperty("wles.realm.1");
if (realm1Name != null) {
configId = realm1Name;
} else {
configId = DEFAULT_CONFIGURATION_ID;
}
}
} catch (java.io.IOException e) {
// File does not exist - ignore and set configId to default value
configId = DEFAULT_CONFIGURATION_ID;
}
}
return configId;
}

protected SecurityRuntime initializeSSM(String configId) {
SecurityRuntime rt = null;

// Initialize this applications configuration
debugPrint("Initializing the Security Runtime for configId--> "+configId);
AppConfig cfg = new AppConfig("Java API Example Application");

cfg.useConfiguration(configId);
//
// Add this application naming definitions to the config
try {
// default file name located in the working directory of this project. This
// API call is required with the contents of this file.
cfg.addNameAuthorityDefinitionFile("exampleNames.xml");

} catch (FileNotFoundException fnfExc) {
System.out.println(fnfExc.getLocalizedMessage());
return rt;
}


debugPrint("Cfg AppName is:"+cfg.getApplicationName());
debugPrint("Cfg Client UID is:"+cfg.getClientUID());
String list[] = cfg.getPolicyDomainURLs();

if (list != null ) {
for (int i=0;i Access Allowed: " + String.valueOf(accessResult.isAllowed()));
debugPrint("---> Decision Time: " + accessResult.getDecisionTime().toString());

// By default the data is returned separated by the rule which generated it (i.e. one response context per rule).
// The "getMergedContexts" method will merge all the response contexts into a single context.
HashMapContext responseContext =
(HashMapContext)collector.getMergedContexts();
if (responseContext != null) {
if (responseContext.size() != 0) {
AppContextElement[] res =
responseContext.getElements(responseContext.getNames());
for (int i = 0; i < responseContext.size(); i++) {
debugPrint(" Response context: " +
res[i].getName() + "=" +
res[i].getValue());
}
} else {
debugPrint(" Response context has 0 elements");
}
} else {
debugPrint(" Response context is NULL");
}
collector.clear();

} catch (Exception e) {
System.out.println(e.getLocalizedMessage());
}

return accessResult;
}

private void debugPrint(String s) {
if (DEBUG)
System.out.println(s);
}

} // of class