54 Secure End-to-End Portlet Applications

This chapter describes how to authenticate and authorize portlet services, as well as configure key and credential stores. The process of securing portlet services is similar to that of securing web services.

54.1 Introduction to Securing End-to-End Portlet Applications

In Oracle Fusion Applications, portlets are WSRP portlets, therefore, web services. Oracle Web Services Manager (WSM) policies secure portlets, in the same way that they secure ordinary web services.

Oracle Web Services Manager implements web service security, and allows for run time enforcement and declarative policy attachment within Oracle Fusion Middleware.

Oracle Fusion applications make use of an Oracle WSM feature called global policy attachment (GPA). In GPA, policies are not attached locally, but specified at a global level. At runtime, components inherit the global policy and Oracle WSM enforces it.

For each portlet, these four ports require Oracle WSM policies:

  • WSRP_v2_Markup_Service

  • WSRP_v2_PortletManagement_Service

  • WSRP_v2_Registration_Service

  • WSRP_v2_ServiceDescription_Service

Only the WSRP_v2_Markup_Service markup port requires an authentication policy. By default, no policy should be locally attached to the markup port; this port will inherit the policy from GPA.

However, if the WSRP_v2_Markup_Service port has unique requirements not fulfilled by GPA, then a locally attached policy will be necessary. Additionally, if the locally attached policy specifies message protection or SSL, the necessary key store setup must be in place.

The three non-markup ports are anonymous and therefore you will need to locally attach a "no behavior" policy (defined by oracle/no_authentication_service_policy) to override GPA.

The requirements for the client counterparts for each of these ports is the same. Clients of the WSRP_v2_Markup_Service port inherit GPA, and clients of the three non-markup ports propagate an anonymous token defined by the oracle/no_authentication_client_policy policy.

The following table summarizes the policies attached to the portlet service and the client.

Table 54-1 Recommended Oracle Web Services Manager Policies for Oracle Fusion Portlets

Port Service Side Policy Client Side Policy

WSRP_v2_Markup_Service

No local policy. Inherits from GPA, which by default is oracle/wss_saml_or_username_token_service_policy.

No local policy. Inherits from GPA, which by default is oracle/wss_saml_or_username_token_client_policy.

WSRP_v2_PortletManagement_Service

Local anonymous policy:

oracle/no_authentication_service_policy

Local anonymous policy:

oracle/no_authentication_client_policy

WSRP_v2_Registration_Service

Local anonymous policy:

oracle/no_authentication_service_policy

Local anonymous policy:

oracle/no_authentication_client_policy

WSRP_v2_ServiceDescription_Service

Local anonymous policy:

oracle/no_authentication_service_policy

Local anonymous policy:

oracle/no_authentication_client_policy

To override GPA and secure end-to-end portlet applications with a locally attached policy:

  • Secure the portlet service.

  • Secure the portlet client.

  • Register the key store.

  • Write to the credential store.

54.2 Secure the Portlet Service

Securing the portlet service with a locally attached policy that overrides GPA involves the following main steps:

  • Authenticating the service

  • Configuring the key store and credential store

  • Authorizing the service

54.2.1 How to Authenticate the Service

Authenticating the service is necessary only in two cases:

  • When applying the "no behavior" policy to the anonymous ports.

  • When GPA is being overridden for the WSRP_v2_Markup_Service port.

When a policy is attached locally, Oracle ADF must authenticate the portlet service against an Oracle Web Services Manager policy, such as wss10_saml_token_with_message_protection_service_policy. In addition, it is necessary to configure security for the Oracle Fusion web application EAR file.

Authenticating the services involves the following main steps:

  • Attach the policy (for example, wss10_saml_token_with_message_protection_service_policy) to the provider. You can do this in one of the following ways:

    • Use Oracle Enterprise Manager.

    • Alternatively, manually update oracle-webservices.xml. This is a packaging artifact, meaning it is not available in Oracle JDeveloper during design time. To edit the file, deploy your application to an EAR file. Extract the oracle-webservices.xml file, update it and repackage it into the EAR file.

To edit the oracle-webservices.xml file when overriding GPA:

Open the oracle-webservices.xml file, find port-component name="WSRP_v2_Markup_Service" and add the code shown in the following example.

Example 54-1 Edit the oracle-webservices.xml File

<port-component name="WSRP_v2_Markup_Service" style="document" bindingQName="{urn:oasis:names:tc:wsrp:v2:bind}WSRP_v2_Markup_Binding_SOAP" enabled="true" schemaValidateInput="false">
   <policy-references>
      <policy-reference enabled="true" uri="oracle/wss10_saml_token_with_message_protection_
         service_policy" category="security"/>
      </policy-references>
   <operations>
      <operation name="performBlockingInteraction" inputName="performBlockingInteraction"
         outputName="performBlockingInteractionResponse"
         input="{urn:oasis:names:tc:wsrp:v2:types}performBlockingInteraction" use="literal"/>
      <operation name="releaseSessions" inputName="releaseSessions"
         outputName="releaseSessionsResponse"
         input="{urn:oasis:names:tc:wsrp:v2:types}releaseSessions" use="literal"/>
      <operation name="getMarkup" inputName="getMarkup" outputName="getMarkupResponse"
         input="{urn:oasis:names:tc:wsrp:v2:types}getMarkup" use="literal"/>
      <operation name="handleEvents" inputName="handleEvents" outputName="handleEventsResponse"
         input="{urn:oasis:names:tc:wsrp:v2:types}handleEvents" use="literal"/>
      <operation name="initCookie" inputName="initCookie" outputName="initCookieResponse"
         input="{urn:oasis:names:tc:wsrp:v2:types}initCookie" use="literal"/>
      <operation name="getResource" inputName="getResource" outputName="getResourceResponse"
         input="{urn:oasis:names:tc:wsrp:v2:types}getResource" use="literal"/>
   </operations>
   <!-- start:deployment time generated info -->
   <deployment>
     <tie-class-name>oasis.names.tc.wsrp.v2.bind.runtime.WSRP_v2_Markup_Binding_SOAP_
        Tie</tie-class-name>
     <service-qname namespaceURI="urn:oasis:names:tc:wsrp:v2:wsdl" localpart="WSRP_v2_Service"/>
     <soap-version>soap1.1</soap-version>
   </deployment>
   <!-- end:deployment time generated info   -->
     <servlet-link>WSRP_v2_Markup_Service</servlet-link>
</port-component>

54.2.2 How to Configure the Key Store and Credential Store

By default, a globally attached policy profile specifies (authentication [AuthN]) and there is no need to use Oracle Enterprise Manager to configure a key store or a credential store. You only need to perform this task when a policy has a message protection or a SSL profile.

The key store contains the signing and encryption keys used to encrypt and decrypt messages. The key store itself and all the keys are password protected. The keys are also referred to using aliases, which are stored, along with their corresponding passwords, in the credential store. When accessing the key store, query the credential store first for the necessary aliases and passwords.

You can verify the creation of the key store and credential store as follows.

To verify the creation of the key store and credential store:

  1. Open $DOMAIN_HOME/config/fmwconfig/jps-config.xml.
  2. Verify the existence of the entry shown in the following example. This code should be configured out of the box.
  3. Make sure the default context references the key store and credential store service instances as shown in the following example.

    Note:

    There is no need to restart your domain if this configuration is already in place.

Example 54-2 Verify the credstore and keystore serviceInstance Elements

<serviceInstance location="./" provider="credstoressp" name="credstore">
            <description>File Based Credential Store Service Instance</description>
</serviceInstance>

<serviceInstance name="keystore" provider="keystore.provider" location="./default-keystore.jks">
            <description>Default JPS Keystore Service</description>
            <property name="keystore.type" value="JKS"/>
            <property name="keystore.csf.map" value="oracle.wsm.security"/>
            <property name="keystore.pass.csf.key" value="keystore-csf-key"/>
            <property name="keystore.sig.csf.key" value="sign-csf-key"/>
            <property name="keystore.enc.csf.key" value="enc-csf-key"/>
</serviceInstance>

Example 54-3 Default Context References to the Credential Store and Key Store

<jpsContext name="default">
            <serviceInstanceRef ref="credstore"/>
            <serviceInstanceRef ref="policystore.xml"/>
            <serviceInstanceRef ref="audit"/>
            <serviceInstanceRef ref="idstore.ldap"/>
            <serviceInstanceRef ref="keystore"/>
</jpsContext>

54.2.3 How to Authorize the Service

Oracle ADF Security is responsible for authorizing portlets, that is, Oracle ADF Security decides whether a portlet is available to a given user by checking it against the Oracle Platform Security Services (OPSS) policy store. Portlets are just one way of exposing local task flows to remote applications. A component called a portlet bridge is responsible for bridging between portlets and task flows. A portlet bridge enables exposing a task flow as a portlet.

After you create an entitlement grant for the desired task flow in jazn-data.xml, you must create a resource grant for the portlet bridge component to the authenticated role, as shown in the following example.

The following examples shows an entitlement grant enabling access to the task flow.

Note when the Oracle Fusion application needs to provide anonymous access to a portlet, the bridge wrapper task flow needs a grant to the anonymous-role, and the markup port needs a no_authentication policy, or it can use GPA, but needs to specify a Default User in the producer registration, using a valid guest user account, as described in Securing the Portlet Client.

Example 54-4 Resource Grant to the Authenticated Role

<jazn-policy>
    <grant>
       <grantee>
           <principals>
               <principal>
                    <class>oracle.security.jps.internal.core.principals.
                           JpsAuthenticatedRoleImpl</class>
                    <name>authenticated-role</name>
                </principal>
           </principals>
        </grantee>
        <permissions>
              <permission>
                  <class>oracle.adf.controller.security.TaskFlowPermission</class>
                  <name>/WEB-INF/adfp-portlet-bridge-container.xml
                        #adfp-portlet-bridge-container</name>
                  <actions>view</actions>
              </permission>
        </permissions>
    </grant>
...
</jazn-policy>

Example 54-5 Entitlement-Based Policy Definition in the jazn-data.xml File

<?xml version="1.0" ?>
<jazn-data>
  <policy-store>
    <applications>
      <application>
        <name>MyApp</name>
                
        <app-roles>
        <app-role>
          <name>AppRole</name>
          <display-name>AppRole display name</display-name>
          <description>AppRole description</description>
          <guid>F5494E409CFB11DEBFEBC11296284F58</guid>
          <class>oracle.security.jps.service.policystore.ApplicationRole</class>
        </app-role>
      </app-roles>
                
      <!-- resource-specific OPSS permission class definition -->
      <resource-types>
        <resource-type>
          <name>TaskFlowResourceType</name>
          <display-name>Task Flow</display-name>
          <description>Task Flow resource type</description>
          <matcher-class>oracle.adf.controller.security.
                                    TaskFlowPermission</matcher-class>
          <actions-delimiter>,</actions-delimiter>
          <actions>view,customize,grant,personalize</actions>
        </resource-type>
      </resource-types>
                
      <resources>
        <resource>
         <name>/WEB-INF/my-task-flow.xml#my-task-flow</name>
          <display-name>my-task-flow</display-name>
          <description>/WEB-INF/my-task-flow</description>
          <type-name-ref>TaskFlowResourceType</type-name-ref>
        </resource>
      </resources>
                
      <!-- entitlement definition -->
      <permission-sets>
        <permission-set>
          <name>MyPortletEntitlement</name>
          <member-resources>
            <member-resource>
              <resource-name>/WEB-INF/my-task-flow.xml#
                                           my-task-flow</type-name-ref>
              <type-name-ref>TaskFlowResourceType</type-name-ref>
              <display-name>my-task-flow</resource-name>
              <actions>view</actions>
            </member-resource>
          </member-resources>
        </permission-set>
      </permission-sets>
                
      <!-- Oracle function security policies -->
      <jazn-policy>
        <!-- function security policy is a grantee and permission set -->
        <grant>
          <!-- application role is the recipient of the privileges -->
          <grantee>
            <principals>
              <principal>
                <class>
                   oracle.security.jps.service.policystore.ApplicationRole
                </class>
                <name>AppRole</name>
              </principal>
            </principals>
          </grantee>

          <!-- entitlement granted to an application role -->
          <permission-set-refs>
            <permission-set-ref>
              <name>MyPortletEntitlement</name>
            </permission-set-ref>
          </permission-set-refs>
        </grant>
      </jazn-policy>
    </application>
  </applications>
 </policy-store>
</jazn-data>

54.3 Secure the Portlet Client

Securing the portlet client is necessary only when applying the "no behavior" policy to the anonymous ports.

Securing a portlet consumer, or client, means enabling identity propagation. You can enable identity propagation while registering the portlet producer in Oracle JDeveloper. When registering the portlet producer, make sure you select following values in the WSRP Portlet Producer Registration wizard.

In the Configure Security Attributes window, select the following:

  • Token Profile: Select a policy that overrides GPA. For example, you might select No Authentication Client Policy when locally attaching a policy for any of the three non-markup ports.

  • Configuration: Select Default.

  • Default User: Leave empty or enter a valid guest user account ID to propagate to the portlet.

    Note that Default User is only used when the consumer identity is in fact anonymous. In this case, the Default User field lets you specify some valid identity that is necessary to propagate to the portlet, when the consumer is anonymous, and the producer needs to receive a valid identity.

Within the portlet consumer domain, make sure the key store and credential store are the same ones used by the portlet producer or service. The key store and credential store are located at $DOMAIN_HOME/config/fmwconfig. For more information, see the section about verifying the creation of the key store and credential store under How to Configure the Key Store and Credential Store.

54.4 Register the Key Store and Writing to the Credential Store

By default, globally attached policy profile specifies (authentication [AuthN]) and there is no need to use Oracle Enterprise Manager to register a key store or create a credential store. You only need to perform this task when a policy profile offers message protection or SSL.

However, if you need to configure another key store for your domain, use Oracle Enterprise Manager to register the key store and write to the credential store.

54.4.1 How to Register the Key Store and Write to the Credential Store

To register the key store and write to the credential store:

  1. In Oracle Enterprise Manager, expand your domain. Select WebLogic Domain > WebLogic Domain Name.
  2. In the right-hand pane, click the WebLogic Domain menu at the top of the page and select Security > Credentials.
  3. If there is no map called oracle.wsm.security, create one. If the map exists, skip this step. The following figure displays the Create Map window.

    Figure 54-1 Create a Map If None Exists

    Described in the surrounding text.
    • Click the Create Map button.

    • For the Map Name, enter oracle.wsm.security.

      Do not create any keys. Keys are created when configuring the domain's service provider.

  4. In the right-hand pane, click the WebLogic Domain menu at the top of the page and select Security > Security Provider Configuration.
  5. In the Service Provider Configuration page, under the Key Store section, click the Configure button. The Service Provider Configuration page is shown in the following figure.

    Figure 54-2 Click the Configure Button

    Described in the surrounding text.
  6. If the Keystore Path displays ./default-keystore.jks, follow the instructions here. Otherwise, skip this step.

    Uncheck the Configure KeyStore Management box and click OK. This displays the window shown in the previous figure.

    Under the Keystore section, click Configure again and enter the following information. The file producer.jks is assumed to be located under the directory path $DOMAIN_HOME/config/fmwconfig which contains a certificate alias called producer. The following figure displays the Keystore Configuration page.

    Figure 54-3 Configure the Keystore

    Described in the surrounding text.
    • Keystore Path: Enter the path of the keystore, in this case ./producer.jks.

    • Password/Confirm Password: Enter the required password, then confirm the password.

    Signature Key

    • Key Alias: Enter the name of the signature key.

    • Signature Password/Confirm Password: Enter the required password, then confirm the password.

    Encryption Key

    • Crypt Alias: Enter the name of the encryption key.

    • Crypt Password/Confirm Password: Enter the required password, then confirm the password.

  7. Restart your domain.

54.4.2 What Happens When You Register the Key Store and Write to the Credential Store

Entering this information enables the creation of keystore-csf-key, sign-csf-key and enc-csf-key in the credential store of the domain. You can verify that the keys have been created by viewing the credential store page of the domain in Oracle Enterprise Manager.

54.5 Maintain Application Session Context Across Web Service Requests

When the user invokes a function defined by a web service, the current application session context must be propagated across web service requests. The application session context contains important information that is stored for the duration of the user's HTTP session. This includes information that defines a context for the application, such as its language preferences, date, and number formatting.

In order for application session context propagation to occur, you need to register the ApplSessionContext class with the context interceptor infrastructure. Then when a SOAP request is generated by the invoked web service, the request calls out to the infrastructure and adds the application session context onto the SOAP payload.

To register the ApplSessionContext class, you must add the oracle.applcore.config library to the weblogic-application.xml file for projects on both ends of the web service request. In order for propagation to work, both the portlet consumer and the portlet producer must have this library.

Before you begin:

It may be helpful to have an understanding of application user sessions. For more information, see Implementing Application User Sessions.

You will need to complete this task:

To add the Oracle Applications Core (Config) JDev library to the classpath:

  1. In the Application Resources panel of the Application Navigator, double-click the weblogic-application.xml file of the project that defines the portlet producer.
  2. In the source editor for the file, add the following lines alongside the other <library-ref> tags:
    <library-ref>
      <library-name>
        oracle.applcore.config
      </library-name>
    </library-ref>
    

    The order of the <library-ref> tags is not important; however, all <library-ref> tags must be grouped together.

  3. Repeat this change in the project that defines the portlet consumer.

    In order for propagation to work, both the portlet consumer and the portlet producer must have the oracle.applcore.config library.