Wednesday 29 August 2012

Using Identity Switching from SOA Suite


My requirement for Identity Switching came when I was implementing a BPM process. We had a process where a user would initiate a simple process and attach a relevant document. This document then needed to be checked in to UCM using the provided web service.

The original setup had the BPM process authenticating as a system user when calling the UCM web service, regardless of which user actually approved the task. This worked, but meant that every document appeared to be checked in as that system user, and not as the user who actually uploaded the document.

The solution to this problem was to use Identity Switching to effectively authenticate as one user, but then switch the SAML token that is actually used when calling the UCM Web Service.

This blog post uses the UCM Web Service as an example, but can be applied to any web service that has the oracle/wss11_saml_token_with_message_protection_service_policy applied to it. For instructions on how to do apply this policy to the UCM (or another) web service, see Securing a Web Service on WebLogic

Setting Up the JDeveloper Project

The first step is to create an empty JDeveloper SOA Application/Project:
  1. Open JDeveloper and select File->New->SOA Application
  2. Enter an Application Name and click Next
  3. Enter a Project Name and click Next
  4. Select Empty Composite and click Finish

Adding the External Web Service

Now that you have your empty composite you want to add the Web Service. To do this, first open the the composite.xml file then drag a Web Service adapter from the Component Palette onto the External References right-hand column. You will be prompted to enter your web service details. I have used the UCM Web Service:

Option 1 - Identity Switching Using Mediator

I find the Mediator is simpler to implement and makes more sense if all you are doing is simply setting up Identity Switching.

For a Mediator, drag the Mediator Service Component from the Component Palette onto the Components central column of the composite.xml. I have set up my Mediator to be based off of the same WSDL as the Web Service to keep things simple. See below for details:


Connect the Mediator to the Web Service on the composite.xml.

Because the composite input is the same type as the web sevrice input, the Mediator implemntation is complete. If you used a different input schema for your Mediator, you will most likely need transform your Mediator and Web Service inputs and outputs.
    The only step left is to set up the actual Identity Switching in the mediator:
    1. Open the Mediator
    2. Under the Static Routing click the button beside the first Assign Values field for the request
    3. Click the Add (plus) button
    4. In the From column, select constant from the drop down
    5. Enter the username of the user whose identity you want to switch to e.g. usera
    6. In the To column, select property from the drop down
    7. From the list of available property values, select javax.xml.ws.security.auth.username
    8. Click OK
    9. Save all files
    Below are my Routing Rules after implementing the Mediator:


    Option 2 - Identity Switching Using BPEL

    Identity Switching can also be implemented using a BPEL Process which can be useful if you are trying to achieve more than Identity Switching in your Composite.

    For a BPEL Process, drag the BPEL Process Service Component from the Component Palette onto the Components central column of the composite.xml. I have set up my BPEL Process to be based off of the same WSDL as the Web Service to keep things simple. See below for details:


    Connect the BPEL Process to the Web Service on the composite.xml.

    The BPEL Process does not automatically map between the process and Web Service input/output. As such you will need to add:
    1. An Invoke which connects to your Web Service
    2. A Transform (or Assign) to map the BPEL process input to the Web Service input
    3. A Transform (or Assign) to map the Web Service output to the BPEL process output
    The BPEL process should resemble that below:



    The final steps are to perform the actual Identity Switching on the BPEL Invoke:
    1. Open the BPEL Process
    2. Double Click the Invoke and select the Properties tab
    3. Locate the property named javax.xml.ws.security.auth.username
    4. In the Value column, click the "..." lookup button
    5. Select the Expression radio button and enter the username string of the user whose identity you want to switch to e.g. 'usera'
    6. Click OK twice
    7. Save all files

    Securing the Endpoints

    At this point, all of the relevant service endpoints have been added to the composite.xml, so we are ready to set their security. For this example, the composite will require a simple username/password token, and will use this token to authenticate against the UCM web service, but switch the Identity.

    The first step is to setup the UCM web service for Identity Switching:
    1. Right click on the Web Service under External References and select Configure WS Policies...
    2. Click the Add button beside the Security heading
    3. Select oracle/wss11_saml_token_identity_switch_with_message_protection_client_policy
    4. Click OK to both popups
    5. Save All files
    Next, set the security for the endpoint of our BPEL/Mediator:
    1. Right click on the Exposed Service and click Configure WS Policies...
    2. Click the Add button beside the Security heading
    3. Select oracle/wss_username_token_service_policy
    4. Click OK to both popups
    5. Save All files

    Adding System Policies

    Before a SOA Composite can use Identity Switching, it must be given explicit permission. The easiest way to do this is to log on to Enterprise Manager, right click on your domain and select Security ->System Policies:


    From the System Policies screen:
    1. Click the Create... button.
    2. Enter a Code Base of file:${common.components.home}/modules/oracle.wsm.agent.common_11.1.1/wsm-agent-core.jar
    3. Click the Add button under Permissions
    4. Check the Select here to enter details for a new permission checkbox
    5. Enter the following details:
      • Permission Class: oracle.wsm.security.WSIdentityPermission
      • Resource Name: *
      • Permission Actions: assert
    6. Click OK twice to save your changes
    You can also use the following WLST command to create the same System Policy as above:

    grantPermission(codeBaseURL='file:${common.components.home}/modules/oracle.wsm.agent.common_11.1.1/wsm-agent-core.jar', permClass="oracle.wsm.security.WSIdentityPermission", permTarget="resource=*", permActions="assert")

    NOTE: The value for Resource Name above should ideally be the name (and version) of your particular composite e.g. IdentitySwitchingComposite[1.0]. However, I could not seem to get this working correctly, so took the easy way out and entered "*", so that all composite would be granted access to perform Identity Switching.

    Testing Identity Switching

    Now that your Composite has been developed and the necessary System Policies have been created, you can finally deploy your Composite for testing. To test I call my Composite passing in the credentials of userb but the update of metadata in UCM is recorded against usera

    Securing a Web Service on WebLogic

    This post outlines how to apply WS-Policies to Web Service endpoints on a WebLogic server using the UCM Web Service as an example. It also details how to fix potential issues when securing web services in a multi-machine domain.

    Securing the Endpoint

    • Log into the Admin Console (http://<server>:7001/console)
    • Select Deployments from the left menu
    • Locate and select the relevant web service deployment. I am using GenericSoapService under the Oracle UCM Web Services deployment
    • Select the Configuration tab, then the WS-Policy sub tab
    • Click the relevant Service Endpoint. I am using GenericSoapPort
    • If prompted, select OWSM and click Next
    • Add the desired policy to the Chosen Endpoint PoliciesFor the UCM Web Service, only the following two policies are supported:
    oracle/wss11_saml_token_with_message_protection_service_policy
     oracle/wss11_username_token_with_message_protection_service_policy
    • Click Finish. IMPORTANT: Take note of the deployment plan path. For me, it was:

    <MW_HOME>/Oracle_ECM1/ucm/idc/components/ServletPlugin

    • If prompted, click OK to confirm on the Save Deployment Plan screen.
    • Activate Changes
    If you are running a domain with multiple machines, you may see an an error message at the top of the screen indicating that the Plan.xml file was not found. If this occurs, follow the instructions below.

    Configuring a Multi-Machine Domain

    When you update the WS-Policy for the web service deployment, a Plan.xml file (and other supporting files) are created on the machine where Admin Server is running. If your web service is deployed to any other Managed Servers which are running on separate machines, these supporting files will not exist on these machines. This is why you receive the Plan.xml not found error.
    This problem is easily fixed by copying the relevant files from the Admin Server machine to the same location on every machine with a Managed Server which has the relevant Web Service deployed to it. 
    For my UCM Web Service example, I had to copy the Plan.xml:
    <MW_HOME>/Oracle_ECM1/ucm/idc/components/Plan.xml
    And the following directory:
    <MW_HOME>/Oracle_ECM1/ucm/idc/components/ServletPlugin
    From the Admin Server's machine to the same locations on the two machines that were running the UCM Managed servers.
    NOTE: After copying the above files/directories, please check the permissions are the same/similar to those set on the Admin Server copies.
    Now that all of the supporting files exist in the relevant location, you need to update the your Web Service deployment:
    1. Log into the Admin Console (http://<server>:7001/console)
    2. Select Deployments from the left menu
    3. Check the box beside the relevant deployment. For me, this is Oracle UCM Web Services
    4. Click the Update button at the bottom or top of the page
    5. Make sure that the Redeploy radio button is selected and click Finish
    6. No restart is required

    Missing Users from Active Directory Provider in WebLogic

    I recently encountered an issue when configuring an Active Directory Authentication Provider within WebLogic. The issue was that, although the provider was created successfully, only a dozen or so users were displayed under Users and Groups tab when there should have been several hundred.

    I verified the following:
    1. The Active Directory provider was the default Authentication Provider
    2. The Control Flag of all of the Providers were set to "Sufficient"
    3. I could connect to the Active Directory using JXplorer, meaning I had the correct values for:
      • Host
      • Port
      • Principal
      • Credential (Password)
      • User Base DN
    The issue had to be related to some other property for Users in WebLogic. I reviewed the values I was using:

      • All Users Filter:  <blank>
      • User From Name Filter: (&(cn=%u)(objectclass=user))
      • User Search Scope: subtree
      • User Name Attribute: sAMAccountName
      • User Object Class: user
      • Use Retrieved User Name as Principal: <checked>

    The first thing that jumped out at me was the User From Name Filter. I had simply left the value WebLogic uses by default, which assumes that the User Name attribute is "cn". However, in my case, the username attribute in Active Directory was "sAMAccountName".

    Using JXplorer, I confirmed that the only reason that some Users were being displayed in WebLogic was that their "cn" and "sAMAccountName" attributes were identical. 

    I changed the value of of the User From Name Filter to be "(&(sAMAccountName=%u)(objectclass=user))", and restarted WebLogic. Lo and behold, all users were now being displayed in WebLogic. Success!