Tuesday Jul 26, 2011

EPM 11.1.2 - Externalize EPM permissions to Oracle Entitlements Server / OES

Centralizing security administration is currently the grail of a number of large organizations. It encompasses topics like authentication, single sign on, role based access control, discretionary access control/access control lists, auditing, and so on.

EPM provides centralization for all those aspects, apart from fine grained permissions on specific products artifacts.

The example below demonstrates how to leverage Oracle Entitlement Server to centralize and externalize specific EPM permissions. It is using Essbase filters as example.

Important note: this post does not cover the customization step by step. This is a general guideline, quite some work is required for an effective custom integration.

What is OES?

See http://www.oracle.com/technetwork/middleware/oes/overview/index.html

As a simplification for our example, OES is providing authorizations for any type of resource for a specific user/group, under a constraint.

OES overview

How can it be used with EPM, and specifically Essbase?

If you define an Essbase filter as an OES resource, both the permission on the filter, and the filter definition itself can be retrieved by Essbase through java code. The principle is to query OES at Essbase login time to get the filters, and then set the filters in Essbase dynamically.

Main steps:

- in OES admin ui: create an Essbase filter in OES resource hierarchy, as well as attribute "read", "write", "metaread", "none" matching Essbase filter definition

- in OES admin ui: create an action "GetEssbaseFilterForUser" in OES

- in OES admin ui: create the authorization policy for the filter for a specific user.

- Setup Essbase to use CSS authentication, and implement a custom authentication module.

- Configure OES  policy decision points

- In the CSS custom authentication module, add OES api code to query OES to get the filter granted to the user, as well as filter definition

- In the CSS custom authentication module, add the filter dynamically to Essbase through APS java api.

Setting the resources and authorizations in OES

An Essbase filter could look like this in OES 10g (same concept applies for OES 11g):

As part of a resource hierarchy, the filters are created below the App/cube:

OES resource hierarchy with Essbase filter

The resource attribute contains the filter definition:

OES resource attribute - key value pairs

You can set the authorization policy for this resource, for a given action/permission you have created ("GetEssbaseFilterForUser" for instance). Make sure you set the report_as entries in the constraints, this will allow OES to provide the resource attribute as part of the response to an authorization request;

OES constraint report_as to provide resource attribute

Note you can also add day and time constraints, ldap attributes constraints and other dynamic ones. This is very interesting for generation and granting of filters based on dynamic attributes.

Retrieving the permissions and resources in Essbase

Essbase can rely on CSS custom authentication module to defer authentication to your custom java code. In this code, you can call OES to authenticate user, as well as retrieve permissions.

Custom authentication whitepaper available here: http://www.oracle.com/technetwork/middleware/bi-foundation/epm-custom-authentication-wp-129437.pdf

OES api to retrieve the list of granted resources (the filter assigned to user/group)

 Create an oesess.properties containing your oes action and other properties:

Techuser=anadminuser     (this user is updating the security filter in Essbase after user has logged in)

// For OES authentication code, please see OES java ssm samples

                    // you can reuse part of the samples provided in /Oracle/Middleware/ales32-ssm/java-ssm/examples/QueryResources in OES 10g

          // Authentication complete - now call isAccessAllowed() (for query access and query resources)

            HashMapContext appContext = new HashMapContext();
            //request query resources
            AppContextElement qrElement = new SimpleContextElement(ASI_NAMESPACE_AUTHORIZATION, ASI_UNQUALIFIED_QUERY_RESOURCES, "");
            //request response contexts
            AppContextElement collectorElement =SimpleResponseContextCollector.makeContextElement();
            SimpleResponseContextCollector collector =(SimpleResponseContextCollector) collectorElement.getValue();

              ResourceBundle oesres = ResourceBundle.getBundle("oesess");
              String clippingResource= oesres.getString("RootResource");
              RuntimeResource resource = new RuntimeResource(clippingResource, "exampleResource");
              String actionStr= oesres.getString("ListFiltersAction");
              RuntimeAction action = new RuntimeAction(actionStr, "exampleAction");              
              AccessResult accessResult = null;
              try {
                accessResult = atzSvc.isAccessAllowed(ident,

                AppContext responseContext = collector.getMergedContexts();
                Collection gvalues=null;
                // Get all the granted resources
                AppContextElement granted = responseContext.getElement(ASI_QUERY_RESOURCE_GRANTED);
                if (granted != null && granted.getValue() != null) {
                 gvalues = (Collection) granted.getValue();

                 System.out.println("Granted filters are: ");
                  for (Iterator i = gvalues.iterator(); i.hasNext();) {
                    System.out.println("\t" + i.next());
                else {
                  System.out.println("No Granted filters.");

                for(Iterator i = gvalues.iterator(); i.hasNext();) {

                        String filter=(String) i.next();
                        int ifil=filter.lastIndexOf(clippingResource);
                        String shortfilter=filter.substring(ifil);

                        System.out.println("Querying attributes for filter:"+shortfilter);
                        RuntimeResource filterres=new RuntimeResource(shortfilter,"exampleResource");
                        //check access t  resource directly
                         appContext = new HashMapContext();
                        String appAttrName  = actionStr;

                         AppContextElement transContext = new SimpleContextElement(appAttrName, "");
                        EssFilter essf=null;
                        String[] fnametoks = shortfilter.toString().split("/");
                        essf = getFilterFromResourceAttr(atzSvc, ident,filterres,shortfilter, action, appContext);

                         if (essf != null) {
                            String app=oesres.getString("App");
                            String cube=oesres.getString("Cube");
                            String read=essf.getRead();
                            String write=essf.getWrite();
                            String metaread=essf.getMetaRead();
                            String none=essf.getNone();
                            //create essbase filter

                            boolean ess=false;
                            String[] tokens = ident.toString().split(",");

                            String username=tokens[1];
                            ess=essCreateFilter(username,shortfilter, app, cube, read, write, metaread, none);

                } //end iterating over granted filters

OES api to retrieve the attributes of the resource (the filter definition):

static EssFilter getFilterFromResourceAttr(AuthorizationService atzSvc, AuthenticIdentity ident,RuntimeResource resource,
    String filter, RuntimeAction action, HashMapContext appContext) {

       EssFilter essfilter=new EssFilter();   
       ExtendedAccessResult accessResult = null;

       try {
         AppContextElement collectorElement = SimpleResponseContextCollector.makeContextElement();
         SimpleResponseContextCollector collector = (SimpleResponseContextCollector) collectorElement.getValue();

         // request response contexts

         ResourceAction ra=new ResourceAction(resource,action);
         accessResult = atzSvc.isAccessAllowed(

        List arlist=accessResult.getResponses();
        for (Iterator it=arlist.iterator(); it.hasNext();) {
           SimpleContextElement sce = (SimpleContextElement)it.next();
           String scename=sce.getName();
           String scevalue=sce.getValue().toString();


           if (scename.equals("Read")) essfilter.setRead(scevalue);
           if (scename.equals("MetaRead")) essfilter.setMetaRead(scevalue);
           if (scename.equals("None")) essfilter.setNone(scevalue);
           if (scename.equals("Write")) essfilter.setWrite(scevalue);

       } catch (Exception e) {

       return essfilter;

static class EssFilter {
            private String read="";
            private String write="";
            private String metaread="";
            private String none="";

            String getRead() {
            return read;
            String getWrite() {
            return write;
            String getNone() {
            return none;
            String getMetaRead() {
            return metaread;
            boolean setRead(String readfilter) {
            return true;
            boolean setWrite(String writefilter) {
            return true;
            boolean setNone(String nonefilter) {
            return true;
            boolean setMetaRead(String metareadfilter) {
            return true;

Applying the permissions in Essbase

Use APS java api to set the filter on the fly. An api is provided with APS:


IEssCube.IEssSecurityFilter setSecurityFilter(java.lang.String filterName,boolean Active,IEssCube.EEssCubeAccess Access) throws com.essbase.api.base.EssException

Creates or replaces a filter, and starts setting the contents of the filter. If the filter does not already exist, it will first be created by this call. This call must be followed by successive calls to IEssCube.IEssSecurityFilter.setFilterRow() to set all the rows for the filter. To avoid overwriting a filter that already exists, use IEssCube.createSecurityFilter. IEssCube.createSecurityFilter creates only a uniquely named filter for a particular database, but will not overwrite an existing filter of the same name on the same database.

Here is the code example.

    static boolean essCreateFilter(String ident,String filtername,String app,String cube,String read,String write,String metaread,String none) {

            ResourceBundle oesres = ResourceBundle.getBundle("oesess");
            String techuser=oesres.getString("Techuser");
            String techpassword=oesres.getString("Techpass");
            String esssrv=oesres.getString("Server");
            String provider="Embedded";

            IEssbase ess = null;
            try {
            IEssDomain dom = ess.signOn(techuser, techpassword, false, null,provider);
            if( dom==null) System.out.println("signon failed");

            IEssOlapServer olapSvr=null;
            if (dom !=null) {
             olapSvr = dom.getOlapServer(esssrv);

            IEssOlapApplication essapp = olapSvr.getApplication(app);
            IEssCube esscube = essapp.getCube(cube);
            IEssCube.IEssSecurityFilter filter1=null;
            System.out.println("Creating or updating sec filter with japi:"+filtername);
            filter1=  esscube.setSecurityFilter(filtername,true,IEssCube.EEssCubeAccess.READ_WRITE_CUBE_DATA);

            if(filter1!=null && read!=null && !("".equals(read))) {
                System.out.println("Setting filter rows: read:"+read);
                filter1.setFilterRow(read, (short)EssGlobalStrings.ESS_ACCESS_READ);
//do the same for other write, none metaread        

            //adding group access for user
            esscube.setUserOrGroupAccess(ident, IEssCube.EEssCubeAccess.FILTER_ACCESS);

            } catch (EssException err) {
                System.err.println("Error: " + err.getMessage());
            } finally {
                // Sign off
                try {
                    if (ess != null && ess.isSignedOn() == true)
                } catch (EssException x) {
                    System.err.println("Error: " + x.getMessage());
    return true;


Granted filter retrieval