Restrict Root Compartment Access with Oracle Cloud Infrastructure Policies

The OCI Administrators group grants manage acess to all resources in all compartments including the root compartment.  So, any member of this group is considered a super user.  Is a normal practice to keep Administrators members to a small number of users and create additional groups/policies to restrict access to specific compartments. If there’s a […]

Using Oracle Data Integrator (ODI) to Bulk Load Data into HCM-Cloud

Introduction With its capacity to handle complex transformations and large volumes of data, and its ability to orchestrate operations across heterogeneous systems, ODI is a great tool to prepare and upload bulk data into HCM Cloud. In this post, we are looking at the different steps required to perform this task. Overview of the integration […]

Password Policy in OAM 11g R2

One of the features in the new 11G R2 (or 11.1.2) release of Oracle Access Manager that’s been most eagerly anticipated is the support for password policy within the OAM product; that is, the ability for OAM itself to support a subset of pass…

Attaching OWSM policies to JRF-based web services clients

I’ve recently came across a question in one of our internal mailing lists where a person was under the impression that he would have to write code to propagate the identity when making a web service call using OWSM policies. My answer was something like: “depending on the type of your client you may have to write some very small piece of code to attach a policy, but you should not write code at all to either retrieve the executing client identity or to do the propagation itself”. Fortunately, I had an unpublished article that applied 100% to his use case. And here it is now (a little bit revamped).

OWSM (Oracle Web Services Manager) is Oracle’s recommended method for securing SOAP web services. It provides agents that encapsulate the necessary logic to interact with the underlying software stack   on both service and client sides. Such agents have their behavior driven by policies. OWSM ships with a bunch of policies that are adequate to most common real world scenarios.

Applying policies to services and clients is usually a straightforward task and can be accomplished in different ways. This is well described in the OWSM Administrators Guide. Looking from the client perspective, the docs describe how to attach policies to SOA references, connection-based clients (typically ADF-based clients) and standard Java EE-based clients using either Enterprise Manager or wlst.

Oracle FMW components (like OWSM agents) are typically deployed on top of a thin software layer called JRF (Java Required Files), providing for the required interoperability with software stacks from different vendors.

This post is a step-by step showing how to code a JRF-based client and attach OWSM policies to it at development-time using Oracle JDeveloper.

This is a 3-step process:

a) Create proxy-supporting classes;
b) Use the right client programming model;
c) Attach OWSM policy to the client;

1. Creating proxy-supporting classes

Very straightforward.
Select a project and go to File -> New and select Web Services in the Business Tier category. On the right side, choose Web Service Proxy and follow the wizard.

proxy1

2. Picking the right client programming model

For clients on 11g R1 PS2 and later, use oracle.webservices.WsMetaFactory. If your client is going to run on 11g R1 or 11g R1 PS1, use the deprecated oracle.j2ee.ws.common.jaxws.ServiceDelegateImpl. All these classes are available in jrf-client.jar file, located at oracle_common/modules/oracle.jrf_11.1.1 folder in your middleware home installation.

2.1 Code sample using oracle.j2ee.ws.common.jaxws.ServiceDelegateImpl (up to 11g PS1)

...
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.ws.BindingProvider;
import oracle.j2ee.ws.common.jaxws.ServiceDelegateImpl;
import oracle.webservices.ClientConstants;
import oracle.wsm.security.util.SecurityConstants;
import org.w3c.dom.Element;
...
String endpoint = "http://127.0.0.1:7101/B7aFusionWebServices-Model-context-root/MyAppModuleService";
URL wsdlURL = new URL(endpoint+"?WSDL");
ServiceDelegateImpl serviceDelegate = new ServiceDelegateImpl(wsdlURL, new QName("http://xmlns.oracle.com/oracle/apps/", "MyAppModuleService"), oracle.webservices.OracleService.class);
MyAppModuleService port = serviceDelegate.getPort(new QName("http://xmlns.oracle.com/oracle/apps/", "MyAppModuleServiceSoapHttpPort"), MyAppModuleService.class );

InputStream isClientPolicy = <Your_Client_Class_Name>.class.getResourceAsStream("client-policy.xml");
Map<String,Object> requestContext = ((BindingProvider) port).getRequestContext();
requestContext.put(ClientConstants.CLIENT_CONFIG, fileToElement(isClientPolicy));
requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpoint);

// Add other properties here. For identity switching add
// requestContext.put(SecurityConstants.ClientConstants.WSS_CSF_KEY, "<AppID_csf_key>");
port.sayHello(name);
...

// Utility method to convert an InputStream into an org.w3c.dom.Element
public static Element fileToElement(InputStream f) throws IOException, Exception {
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
builderFactory.setValidating(false);
builderFactory.setNamespaceAware(true);
builderFactory.setIgnoringElementContentWhitespace(true);
builderFactory.setIgnoringComments(true);
return builderFactory.newDocumentBuilder().parse(f).getDocumentElement();
}

In this sample, MyAppModuleService is the port interface generated by JDeveloper in the step before.

The parameters to the QName object constructor are the target namespace and the service/port name, both found in the web service wsdl.

2.2 Code sample using oracle.webservices.WsMetaFactory (11g PS2 +)

...
import java.net.URL;
import java.util.Map;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Service;
import oracle.webservices.ClientConstants;
import oracle.webservices.ImplType;
import oracle.webservices.WsMetaFactory;
import oracle.wsm.security.util.SecurityConstants;
import org.w3c.dom.Element;
...

String endpoint = "http://localhost:7101/WebServiceSample2-WebService-context-root/GreetingPort";
URL serviceWsdl = new URL(endpoint + "?wsdl");
QName serviceQName = new QName("http://sample2.webservice/","GreetingService");
QName portQName = new QName("http://sample2.webservice/","GreetingPort");


Service proxyService = WsMetaFactory.newInstance(ImplType.JRF).createClientFactory().create(serviceWsdl, serviceQName);
Greeting port = proxyService.getPort(portQName, Greeting.class);

InputStream clientPolicyStream = Servlet1.class.getResourceAsStream("client-policy.xml");
Element clientConfigElem = this.fileToElement(clientPolicyStream);

Map<String,Object> requestContext = ((BindingProvider) port).getRequestContext();
requestContext.put(ClientConstants.CLIENT_CONFIG , clientConfigElem);
requestContext.put(SecurityConstants.ClientConstants.WSS_CSF_KEY,"servlet1-key");

port.sayHello();

 

In this sample, Greeting is the port interface generated by JDeveloper in the step before.

The parameters to the QName object constructor are the target namespace and the service/port name, both found in the web service wsdl.

3. Attaching the OWSM policy

The OWSM policy is passed as an org.w3c.dom.Element to the requestContext Map. One way to come up with such Element is through an XML file that contains a reference to the actual OWSM client-side policy to be used.

InputStream clientPolicyStream = Servlet1.class.getResourceAsStream("client-policy.xml");
Element clientConfigElem = this.fileToElement(clientPolicyStream);
Map<String,Object> requestContext = ((BindingProvider) port).getRequestContext();
requestContext.put(ClientConstants.CLIENT_CONFIG , clientConfigElem);
Here are the XML file (client-policy.xml) contents. You have to create a file like this and make it available to your application CLASSPATH. It references the OWSM policy to be given to the requestContext Map.
<?xml version="1.0" encoding="UTF-8"?>
<oracle-webservice-clients>
<webservice-client>
<port-info>
<policy-references>
<policy-reference uri="oracle/wss11_saml_token_client_policy" category="security"/>
</policy-references>
</port-info>
</webservice-client>
</oracle-webservice-clients>

 

For SAML-based identity propagation, use any of the SAML client policies.

In this case, the policy retrieves the user name Principal from the Java Subject who is running the client and adds it to a generated SAML token in the SOAP call header.

3.1. Switching Identities

To propagate a new identity rather than the one executing the client, use a username token-based policy. By the way, the sample using oracle.webservices.WsMetaFactory may use oracle/wss_username_token_client_policy as the policy name in order to propagate the identity referred by the servlet1-key csf key.

Map<String,Object> requestContext = ((BindingProvider) port).getRequestContext(); 
requestContext.put(SecurityConstants.ClientConstants.WSS_CSF_KEY, "servlet1-key");

 

“servlet1-key” must match a key entry in the domain-level credential store that holds the username/password pair required for the use case implementation. Here’s how you create a key for OWSM usage in the credential store using wlst:

wls:/offline> connect()
Please enter your username :weblogic
Please enter your password :
Please enter your server URL [t3://localhost:7001] :t3://localhost:7101
Connecting to t3://localhost:7101 with userid weblogic
...
Successfully connected to Admin Server 'DefaultServer' that belongs to
domain 'DefaultDomain'.
Warning: An insecure protocol was used to connect to the
server. To ensure
on-the-wire security, the SSL port or
Admin port should be used instead.
wls:/DefaultDomain/serverConfig>
createCred(map="oracle.wsm.security",key="servlet1-key",user="weblogic",password="welcome1")

 

In this case, the policy retrieves the username/password pair from the credential store and adds it to a generated username token in the outgoing SOAP header.

What if the client is a Java SE application?

So far so good, but what happens when the client runs on a Java SE environment?

a) How do you get a hold of the OWSM policy?

Add oracle_common/modules/oracle.wsm.policies_11.1.1/wsm-seed-policies.jar, available in your middleware home installation, to the client CLASSPATH. All policy files are in it.

b) How to deal with the credential store (for identity switching) ?

You need to supply the client with 2 files:

1 – cwallet.sso, which is a file-based credential store. In order to author cwallet.sso, I recommend that you use wlst’s createCred command. Yes, you’ll need a JRF-enabled Weblogic server to create it.

2 – jps-config.xml, through -Doracle.security.jps.config Java option. In jps-config.xml, make sure there’s a credential store service instance available for the default context pointing to the folder where cwallet.sso is located, as shown in this sample jps-config.xml:

<?xml version = '1.0' encoding = 'UTF-8'?>
<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">
<property value="doasprivileged" name="oracle.security.jps.jaas.mode"/>
<propertySets/>
<serviceProviders>
<serviceProvider class="oracle.security.jps.internal.credstore.ssp.SspCredentialStoreProvider" name="credstore.provider" type="CREDENTIAL_STORE">
<description>Credential Store Service Provider</description>
</serviceProvider>
<serviceProvider class="oracle.security.jps.internal.idstore.xml.XmlIdentityStoreProvider" name="idstore.xml.provider" type="IDENTITY_STORE">
<description>XML-based IdStore Provider</description>
</serviceProvider>
<serviceProvider class="oracle.security.jps.internal.policystore.xml.XmlPolicyStoreProvider" name="policystore.xml.provider" type="POLICY_STORE">
<description>XML-based PolicyStore Provider</description>
</serviceProvider>
<serviceProvider class="oracle.security.jps.internal.login.jaas.JaasLoginServiceProvider" name="jaas.login.provider" type="LOGIN">
<description>Login Module Service Provider</description>
</serviceProvider>
<serviceProvider class="oracle.security.jps.internal.keystore.KeyStoreProvider" name="keystore.provider" type="KEY_STORE">
<description>PKI Based Keystore Provider</description>
<property value="owsm" name="provider.property.name"/>
</serviceProvider>
</serviceProviders>
<serviceInstances>
<serviceInstance provider="credstore.provider" name="credstore">
<property value="./" name="location"/>
</serviceInstance>
<serviceInstance provider="idstore.xml.provider" name="idstore.xml">
<property value="./jazn-data.xml" name="location"/>
<property value="jazn.com" name="subscriber.name"/>
</serviceInstance>
<serviceInstance provider="policystore.xml.provider" name="policystore.xml">
<property value="./jazn-data.xml" name="location"/>
</serviceInstance>
<serviceInstance provider="jaas.login.provider" name="idstore.loginmodule">
<property value="oracle.security.jps.internal.jaas.module.idstore.IdStoreLoginModule" name="loginModuleClassName"/>
<property value="REQUIRED" name="jaas.login.controlFlag"/>
<property value="true" name="debug"/>
<property value="true" name="addAllRoles"/>
<property value="false" name="remove.anonymous.role"/>
</serviceInstance>
<serviceInstance location="./default-keystore.jks" provider="keystore.provider" name="keystore">
<description>Default JPS Keystore Service</description>
<property value="JKS" name="keystore.type"/>
<property value="oracle.wsm.security" name="keystore.csf.map"/>
<property value="keystore-csf-key" name="keystore.pass.csf.key"/>
<property value="sign-csf-key" name="keystore.sig.csf.key"/>
<property value="enc-csf-key" name="keystore.enc.csf.key"/>
</serviceInstance>
</serviceInstances>
<jpsContexts default="default">
<jpsContext name="default">
<serviceInstanceRef ref="credstore"/>
<serviceInstanceRef ref="idstore.xml"/>
<serviceInstanceRef ref="policystore.xml"/>
<serviceInstanceRef ref="idstore.loginmodule"/>
<serviceInstanceRef ref="keystore"/>
</jpsContext>
</jpsContexts>
</jpsConfig>

Hope this helps some of you dear readers out there.

Creating your first OAM 11g R2 domain

So you downloaded the Identity Management R2 release bits, spun up your little test environment and created a WebLogic domain. But the first time you sign in you get the error message “The policy store is not available; please see the log file for more…

Working with OWSM Policies – Part 1 of some

In this post I discuss the available options to work with OWSM (Oracle Web Services Manager) policies in JDeveloper and Enterprise Manager. OWSM is a component available along with the Oracle SOA Suite and provides policy enforcement point (PEP) agents for SOAP-based messages.

Typically, a service policy is attached to a service endpoint to enforce some pre-defined rules (like enforcing a SAML token, Kerberos token, message confidentiality, SSL, etc). And a corresponding client policy is attached to the client in order to transform the outgoing SOAP message, making it suitable to be enforced in the server side.

OWSM Policies in JDeveloper

OWSM supports two types of repositories for its policy files: file system or database.
When working with JDeveloper, you can choose which one you want to use.
By default, JDeveloper reads policies from the file system. To check that out, go to Tools –> Preferences –>WS Policy Store (on left).

image

The File Store Default Location refers to DefaultDomain oracle/store/gmds directory under $JDEV_USER_DIR’s systemxx.x.x.x.xx.xx.xx folder. Policies are under owsm/policies and assertions are under owsm/assertiontemplates.

The App Server Connection option actually refers to a running Weblogic instance that ultimately gets the policies from a database.

Development groups working with custom policies may like the idea of having policies defined in a central location so that everyone can be sure to work against the very same version of policies. The drawback is that you’ll need that server up and running all the time.

When working with SOA and web services, JDeveloper exposes OWSM policies graphically so they can be picked up with a single click. A description of what the policy does is also shown. I strongly recommend reading it, since it can clarify many questions you might have about the policy. If you’re writing a web service proxy and wants to attach a policy, there is no UI and you should know the policy name. Speaking of names, one good aspect is that OWSM policies are named in a very intuitive way. For example, wss11_saml_token_with_message_protection_client_policy says that it is a client policy implementing message protection for SAML 1.1 tokens. In other words, it adds an encrypted and signed SAML 1.1 token to the outgoing SOAP message.

OWSM Policies in Enterprise Manager

JDeveloper is not the single option for policy attachment. Organizations may decide to take such task off developers hands and defer it to sysadmins. That’s accomplished with Enterprise Manager. You navigate to the attachment point and simply pick the policy you want. Policy enforcement starts immediately.

Besides that, Enterprise Manager provides some very convenient ways for working with policies.
There’s a “Create Like” option serving as a template mechanism. During policy creation, you can change several attributes of the original policy as well as add, change or remove specific assertions. By the way, a policy is composed of one or more assertions, who are the ones that actually do the “heavy-lifting”, containing the necessary logic to deal with the SOAP message.

By saving the policy, it gets persisted into the policy repository.

You then have the option to export it to a file. This is useful if you want to consume it directly from the file system (as JDeveloper does by default) and want to add your own assertion implementation class (which is typically the case when you’re developing a custom policy).

When exporting the file, notice that Enterprise Manager messes up with the file name a bit, by changing the “/” (slash) symbol following the “oracle” prefix to an “_” (underscore). You must rename the file, by cutting “oracle_” off the file name. Then simply copy the file to the oracle folder under the gmds/owsm/policies folder mentioned before.

image

If you want to separate out the custom files from the ones shipped by Oracle, you can even create a new folder under gmds, say “custom”, and put your custom policy there. JDeveloper will automatically acknowledge that.

Another very interesting feature I should mention is that Enterprise Manager implements a web service client, allowing  OWSM policies to be tested. For example, let’s say you develop a pair of policies to implement WSS digest-based authentication. Upon attaching the service-side policy to your deployed web service, you should be able to use EM’s testing page to attach the client-side policy to the outgoing SOAP message and verify if your policies are ok.

Next time I will cover how to write custom OWSM policies, including the main java APIs developers should be aware of.

Watch out those code source grants

Code source grants are policies governing the rights of code running in a JVM (Java Virtual Machine). In this article, I talk about 3 common implementation issues when dealing with code source grants in a Weblogic/OPSS (Oracle Platform Security Services) environment.

Code requiring grants are one of the protection mechanisms offered in the Java platform since Java SE 1.2. Java SE 1.2 improved the previous versions by allowing a fine-grained authorization model, opposed to the all-or-nothing model in Java SE 1.0 and 1.1.

In a nutshell, if you want to only allow code from a given jar file to read/write to a file in tmp folder, you can specify the following in one of the java.policy files:

   1: grant codeBase “file://MyApp/MyJar.jar”
   2: {
   3:     permission java.io.FilePermission “/tmp/*” “read/write”;
   4: }

The code base grant along with the permission define what is known as a protection domain.

Then when you run the JVM with the security manager enabled (-Djava.security.manager), any code attempting to read/write to /tmp folder will be checked if it has been granted the permission.

Fair enough.

OPSS does not use the standard java.policy. Instead, it implements JAAS by looking at the configured policy store repository (system-jazn-data.xml by default) as the policy store for code source grants (as well as principal-based grants). Here’s a snippet:

   1: <jazn-data>
2: <policy-store>
   3:          <applications>
   4:              <application>
   5:                  <name>MyApp</name>
   6:                  <jazn-policy>
   7:                      <grant>
   8:                          <grantee>
   9:                              <principals>
  10:                                  <principal>
  11:                                      <class>oracle.security.jps.internal.core.principals.JpsAuthenticatedRoleImpl</class>
  12:                                      <name>authenticated-role</name>
  13:                                  </principal>
  14:                              </principals>
  15:                          </grantee>
  16:                          <permissions>
  17:                              <permission>
  18:                                  <class>oracle.adf.share.security.authorization.RegionPermission</class>
  19:                                  <name>trunk.pagedefs.SearchPageDef</name>
  20:                                  <actions>view</actions>
  21:                              </permission>
  22:                         </permissions>
  23:                      </grant>
  24:                  </jazn-policy>
  25:              </application>
  26:          </applications>
  27:      </policy-store>
  28:      <jazn-policy> 
  29:         <grant>
  30:              <grantee>
  31:                  <codesource>
  32:                      <url>file:${domain.home}/servers/${weblogic.Name}/tmp/_WL_user/MyApp/-</url>
  33:                  </codesource>
  34:              </grantee>
  35:              <permissions>
  36:                  <permission>
  37:                      <class>oracle.security.jps.service.policystore.PolicyStoreAccessPermission</class>
  38:                      <name>context=APPLICATION,name=MyApp</name>
  39:                      <actions>getApplicationPolicy</actions>
  40:                  </permission>
  41:              </permissions>
  42:         </grant>
  43:      </jazn-policy>
  44: </jazn-data>

Lines 28-43 define the code source grant in OPSS standards. Notice it actually resembles a plain java code grant pretty well. This specific grant allows any code deployed under file:${domain.home}/servers/${weblogic.Name}/tmp/_WL_user/MyApp to getApplicationPolicy in the MyApp application policy context.

This leads us to issue #1.

Code source grants must be defined separately from principal-based grants.

In system-jazn-data.xml, principal-based grants are application-scoped, meaning they’re meaningful for a specific application and are defined within the <application> element. Code source grants are referred to as system grants and are defined in the outermost <jazn-policy> element, outside of any <application> element. OPSS is very strict when it comes to policies in LDAP. It won’t accept system grants in application scope.

Observe Weblogic server staging mode.

Within a grant definition, the codesource url element refers to its physical location in the file system. Weblogic server deploys bits into different locations depending on its staging mode. In stage mode, application bits are copied from the AdminServer to a specific directory in the managed servers. By default it is ${domain.home}/servers/${weblogic.Name}/tmp/_WL_user/<application-name>/ (or whatever specified by the staging directory name attribute). In nostage mode, applications are, by default, laid down at ${domain.name}/servers/AdminServer/upload/<application-name>/.

And if you use the embedded Weblogic server in JDeveloper, applications are read from another location: ${domain.home}/../o.j2ee/drs/<application-name>

As a result, code source grants in the policy files must be aligned to the server staging mode.

<application-name> is the actual deployed application name.

It’s a good idea to have something in the build system to target the system grants appropriately to your actual testing and production environments.

Know about AccessController.doPrivileged when invoking protected APIs

The JVM security model correctly takes a conservative approach when evaluating code source grants in the sense that it does not allow a piece of code to “do stuff” in behalf of other another piece of code unless explicitly stated by the application developer. Imagine if you had the rights to delete the contents of a folder and did that upon anyone’s request. Bad things would happen. So the JVM enforces the concept of a trusted path, meaning that whenever a secured operation is called, a permission check is made against all protection domains in the call chain in that executing thread. And this means every protection domain in that call chain must be granted the permission in the policy store. Obviously, the correct set of grants can get very tricky, especially if you’re writing code that is invoked as part of some framework that is also invoked off another framework… You can spend a considerable amount of work figuring out the right code source URLs.

However, the JVM gives us the option of calling the secured API inside an AccessController.doPrivileged block. In this way the JVM gets signaled to not check permissions further up in the call chain. In other words, the protection domain containing that block gets entitled to execute the operation on behalf of anyone calling it without the need of granting anyone else. Here’s some sample code:

   1: JpsContextFactory f = JpsContextFactory.getContextFactory();
   2: JpsContext c = f.getContext();
   3: final PolicyStore ps = c.getServiceInstance(PolicyStore.class);
   4: final String appId = "MyApp";
   5: ApplicationPolicy ap = AccessController.doPrivileged(new 
   6:     PrivilegedExceptionAction<ApplicationPolicy>() {
   7:         public ApplicationPolicy run() throws PolicyStoreException {
   8:             return ps.getApplicationPolicy(appId);
   9:          }
  10:      }, null);
  11: // Continue with the ap object for policy operations.

Lines 5-10 make the getAplicationPolicy method executable by granting only the corresponding protection domain (and nobody else) in the policy store, exactly as in the system-jazn-data.xml shown above.

AccessController.doPrivileged expects either a PrivilegedAction or a PrivilegedExceptionAction type. Both define the run method, where the protected API call is to be made.

It is important that such an approach gets combined with other protection mechanisms, otherwise other code deployed in the container could leverage the privileged code in some “uncool” manner. And if you make that code available to external clients, make sure those interfaces are properly secured (well, this also applies to any sensitive aspect that you expose, regardless of AccessController.doPrivileged usage).

Several ADF apps to one single OPSS policy stripe

In OPSS Artifacts Life Cycle in ADF Applications, I’ve explained how to change the default behavior for migration of authorization policies when deploying applications. Revisiting it, I’ve said that one can specify the MERGE value for jps.policystore.migration param-name in weblogic-application.xml and that is particularly useful in some deployments where more than one application have to share the same policy context (or policy stripe).

A real use case is when a customer wants to hide the concept of how a system is partitioned across ADF applications for security administrators. Most of the times, a security administrator is interested in the policies of the system as whole. This article explains how it can be done.
Before going further, some definitions:

  • Policy Store: repository of policies comprising one or more application policy stripes and code-based grants. There’s only one policy store per WLS domain.
  • Policy Stripe: set of application policies to which one or more applications bind to. One application binds to only one policy stripe.

Clarifying a little bit more, take the following system-jazn-data.xml snippet, the OOTB policy store in WLS domains. In such case, system-jazn-data.xml itself represents the policy store, while OrderEntry#V2.0 and OrderCapture#V2.0 are the policy stripes, defining an application-level scope for authorization policies. In default mode, OrderEntry application does not have access to application policies in OrderCapture#V2.0 policy stripe, and vice-versa.

<?xml version='1.0' encoding='utf-8'?>
<jazn-data>
<policy-store>
<applications>
<application>
<name>OrderEntry#V2.0</name>
<app-roles>
</app-roles>
<jazn-policy>
</jazn-policy>
</application>
<application>
<name>OrderCapture#V2.0</name>
<app-roles>
</app-roles>
<jazn-policy>
</jazn-policy>
</application>
</applications>
</policy-store>
</jazn-data>

When we develop an ADF application in JDeveloper and enables ADF security, the authorization policies you create go into a workspace-level jazn-data.xml under a stripe name that has the same name as the application itself, as show below. Let’s say our application is called OrderEntry. In jazn-data, we would have:

<?xml version=’1.0′ encoding=’utf-8′?>
<jazn-data>
<policy-store>
<applications>
<application>
<name>OrderEntry</name>
<app-roles>
</app-roles>
<jazn-policy>
</jazn-policy>
</application>
</applications>
</policy-store>
</jazn-data>

 

Then if you do nothing and just deploy the application, the policies get migrated to the runtime policy store under an application policy stripe named OrderEntry#V2.0. For our mental sanity, the V2.0 comes from the Weblogic-Application-Version property in the MANIFEST.MF, but this is not the topic of this article.

Now what happens if we want to have OrderEntry and OrderCapture binding to the same policy stripe, say OrderMgmt? We need to add some properties to some deployment descriptors:

1) in weblogic-application.xml:

<application-param>

<param-name>jps.policystore.applicationid</param-name>
<param-value>OrderMgmt</param-value>
</application-param>

Such information is used only at deployment time. It basically tell the OPSS listeners to migrate application policies in jazn-data.xml to OrderMgmt policy stripe in the runtime policy store. In this scenario, the version number is not appended to the stripe name.

2) in web application’s web.xml:

<filter>
<filter-name>JpsFilter</filter-name>
<filter-class>oracle.security.jps.ee.http.JpsFilter</filter-class>
<init-param>
<param-name>enable.anonymous</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>remove.anonymous.role</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>application.name</param-name>
<param-value>OrderMgmt</param-value>
</init-param>
</filter>

Here I have added the init-param application.name to the JpsFilter definition. The param-value must match the value defined in weblogic-application.xml. This information is used only at runtime. It tells the JpsFilter where to bind to when looking for authorization policies. As the JpsFilter intercepts all requests for the Faces Servlet (javax.faces.webapp.FacesServlet), it establishes the policy store context for every request to an ADF artifact.

By repeating this very same configuration across your applications, you can bind any number of applications to the same policy stripe, i.e., the same authorization context and expose a single and consolidated view of your authorization policies to security administrators.

Installing Oracle Policy Automation on WebLogic Server

Today I needed to install Oracle Policy Automation into a WebLogic Server (11g) environment, for integration into a WebCenter Spaces portal (more on that later).   The documentation provides some hints on how to do this, but not all of … Continue reading