4 Implementing Advanced Features in Custom Assertions

You can use the Java API Reference for Oracle Web Services Manager, which specifies packages, interfaces, and methods to implement advanced features in custom assertions.

This chapter describes how to use the API to implement some common features and exception handling. This information is organized into the following sections:

4.1 Supplying Parameters for Custom Assertions

You can access the parameters inside the custom assertion executor using the various interfaces and methods, such as IAssertionBindings, IConfig, IPropertySet, getBindings, getConfigs, getPropertySets, getPropertyByName, and getValue.

For step-by-step instruction on how to supply parameters for custom assertions, see Inputting Parameters to Custom Assertions.

4.1.1 Inputting Parameters to Custom Assertions

You can input parameters to custom assertions by specifying and accessing the parameters inside the custom executor.

To input parameters to custom assertions:

  1. Specify parameters as properties inside your custom assertion. In this example, the orawsp:PropertySet with the name valid_ips defines a group of properties. The orawsp:Property element defines a single property. orawsp:Value defines a list of valid values for the property.
    <orawsp:PropertySet orawsp:name="valid_ips">
        <orawsp:Property orawsp:name="valid_ips" orawsp:type="string"
     orawsp:contentType="constant">
         <orawsp:Value>140.87.6.143,10.178.93.107</orawsp:Value>
         </orawsp:Property>
     </orawsp:PropertySet>
    
  2. Access the parameters inside the custom executor for the corresponding policy. For example, the following code in the execute method of custom assertion's executor class accesses the property valid_ips:
    IAssertionBindings bindings =
     ((SimpleAssertion)(this.assertion)).getBindings();
    IConfig config = bindings.getConfigs().get(0);
    IPropertySet propertyset = config.getPropertySets().get(0);   
    String valid_ips = propertyset.getPropertyByName("valid_ips").getValue();
    

4.2 Examining OWSM Context Properties

You can access OWSM context properties using the IMessageContext interface.

List of interfaces and methods:

  • IMessageContext

  • getServiceURL

  • getProperty

  • getAllProperty

For instructions on how to access the properties using the IMessageContext interface, see Accessing OWSM Context Properties.

4.2.1 Accessing OWSM Context Properties

You can access OWSM context properties in various ways using the IMessageContext interface.

To access OWSM context properties:

  1. To access OWSM context properties inside the custom assertion executor, use the IMessageContext interface. For example:
    IMessageContext messagecontext = (IMessageContext) context;         
    messagecontext.getServiceURL();
    
  2. To access the value of a specific property inside the custom assertion executor, use the IMessageContext interface. For example:

    messagecontext.getProperty("<property name>");

  3. To access all the properties that are used during execution from inside the custom assertion executor, use the IMessageContext interface. For example:

    msgContextProperties = messagecontext.getAllProperties();

4.3 Accessing OWSM Custom Security Assertion

You can access the stages and retrieve the request and response messages inside the custom assertion executor using the various interfaces.

The OWSM custom security assertion has three stages:

  • request: The request stage occurs when a client has made a request and that request is in the process of being delivered to its destination.

  • response: The response stage occurs after the destination has processed the message and is in the process of returning a response.

  • fault: The fault stage occurs in the event of a fault.

The contextual information (such as stages and messages) is passed using context properties and can be obtained by the IMessageContext interface. You can use the following interfaces and methods to access context properties:

  • IMessageContext

  • getStage

  • getRequestMessage

  • getResponseMessage

For instructions on how to access custom security assertion stages and interfaces, see Accessing Request, Response, and Fault Message Objects.

4.3.1 Accessing Request, Response, and Fault Message Objects

To access request, response and fault messages objects:

  1. To access the stage, use the following code within the custom assertion executor:
    IMessageContext.STAGE stage = ((IMessageContext) iContext).getStage();
               if (stage == IMessageContext.STAGE.request) {
                         //handle request
                }
                
                if (stage == IMessageContext.STAGE.response) {
                       //handle response
                }
                
                if (stage == IMessageContext.STAGE.fault) {
                    //handle fault conditions
                }
    
  2. To retrieve the SOAP request message, use the same context oracle.wsm.common.sdk.IMessageContext, as shown in the following example:
    oracle.wsm.common.sdk.SOAPBindingMessageContext soapMsgCtxt=
     (oracle.wsm.common.sdk.SOAPBindingMessageContext) context;
    javax.xml.soap.SOAPMessage soapMessage = soapMsgCtxt.getRequestMessage();
    
  3. To retrieve the SOAP response message, use the same context oracle.wsm.common.sdk.IMessageContext, as shown in the following example:
    oracle.wsm.common.sdk.SOAPBindingMessageContext soapMsgCtxt=
     (oracle.wsm.common.sdk.SOAPBindingMessageContext) context;
    javax.xml.soap.SOAPMessage soapMessage = soapMsgCtxt.getResponseMessage ();
    

4.4 Accessing Parts of a Message Using XPath

You can use XPath expression to access parts of a SOAP message inside the custom assertion executor.

The following topics explain this further:

4.4.1 About XPath Expression

You can access parts of a SOAP message using XPath expression inside your custom policy executor.

In the following SOAP message example, the node arg0 has the value john:

         <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
           <S:Header/>
             <S:Body>
               <ns2:echo xmlns:ns2="http://project1/">
                <arg0>john</arg0>
               </ns2:echo>
             </S:Body>
         </S:Envelope>

In XPath, there are seven types of nodes: element, attribute, text, namespace, processing-instruction, comment, and document nodes. XPath uses path expressions to select nodes in an XML document. Table 4-1 describes some examples of XPath expressions.

Table 4-1 Examples of XPath Expressions

Expression Description

/S:Envelope

Selects from the root element S:Envelope.

/S:Envelope/S:Body

Selects all S:Body elements that are children of S:Envelope

//S:Body

Selects all S:Body elements no matter where they are in a document

4.4.2 Identifying the Value of a Node

Follow the example to identify the value of the node arg0 using the XPath expression.

The following is the example:

//xpath expression that will be used to identify the node arg0
     String xpathStr = "/S:Envelope/S:Body/ns2:echo/arg0";
 

4.4.3 Adding a Namespace to Namespace Context

You can define namespaces for any namespace referenced by the XPath expression and add them to the namespace context.

For example:

     final DefaultNamespaceContext nsContext = new DefaultNamespaceContext();
     nsContext.addEntry("S", "http://schemas.xmlsoap.org/soap/envelope/");
     nsContext.addEntry("ns2", "http://project1/");
              
     XPathFactory xpathFact = XPathFactory.newInstance();
     XPath xpath = xpathFact.newXPath();
     xpath.setNamespaceContext(nsContext);

4.4.4 Retrieving the Value of a Node

Follow the example to retrieve the value of a node using the evaluate method.

The following is the example:

     //This will return node arg0 from SOAP message, here soapElement is  
// org.w3c.dom.Elemet  representation of SOAP message
     org.w3c.dom.Node inputNode = (Node)xpath.evaluate(xpathStr, soapElement,
 XPathConstants.NODE);

4.5 Retrieving Certificates Used by Container for SSL

You can retrieve certificates for SSL by using oracle.wsm.common.sdk.IMessageContext and then accessing the attributes of the certificate.

To retrieve certificates for SSL:

  1. Retrieve SOAP response message using the same context oracle.wsm.common.sdk.IMessageContext, as shown in the following example:
    oracle.wsm.common.sdk.SOAPBindingMessageContext soapMsgCtxt=
     (oracle.wsm.common.sdk.SOAPBindingMessageContext) context;
                 
    
  2. Access the attributes of an X.509 certificate. For example:
    X509Certificate[] certificates = (X509Certificate[])
    soapMsgCtxt.getTransportContext().getAttribute(oracle.wsm.security.util.SecurityConstants.SSL_PEER_CERTIFICATES);
    

4.6 Accessing Transport Properties

You can access the transport properties of HTTP requests and responses by using the same message context as given in the example below and by retrieving the TransportContext from the message context.

To access transport properties for HTTP requests and responses:

  1. Retrieve SOAP response message using the same context oracle.wsm.common.sdk.IMessageContext, as shown in the following example:
    oracle.wsm.common.sdk.SOAPBindingMessageContext soapMsgCtxt= (oracle.wsm.common.sdk.SOAPBindingMessageContext) context;
    
  2. Retrieve TransportContext from message context, as shown in following example:
    ITransportContext transCtx = invokerCtx.getTransportContext();
    

    See the ITransportContext and HttpTransportContext javadoc classes in Oracle Fusion Middleware Java API Reference for Oracle Web Services Manager to see how you can access various properties. Information about these classes is available inside the oracle.wsm.common.sdk package.

4.7 Accessing Credential Store Framework Keys

You can use credential store framework (CSF) to manage the credentials securely, and store, retrieve, and maintain credentials.

To configure and use CSF:

  1. Configure CSF in jps-config.xml.

    For details on configuring credential store using WLST, see Configuring the Credential Store in Securing Web Services and Managing Policies with Oracle Web Services Manager.

  2. You can add, update, or retrieve CSF keys from CSF inside your custom assertion executor.

    You can use the following sample to access CSF keys from credential store.

       final String mapName = "oracle.wsm.security";
       final csfKey = "user.credentials";
       final oracle.security.jps.service.credstore.PasswordCredential userCreds =
     getCredentialsFromCSF(mapName, csfKey);
     
              if (userCreds != null) {
                    System.out.println("name:"+ userCreds.getName());
                    System.out.println("name:"+ new String(userCreds.getPassword()));
                                      }
        
    

    This sample uses the getCredentialsFromCSF method:

    private static oracle.security.jps.service.credstore.PasswordCredential 
    getCredentialsFromCSF(
            final String mapName, final String csfKey) {
            oracle.security.jps.service.credstore.PasswordCredential
            passwordCredential = null;
            try {
                if (csfKey != null) {
                final oracle.security.jps.service.credstore.CredentialStore credStore
                = getCredStore();
                if (credStore != null) {
                passwordCredential = (oracle.security.jps.service.credstore.PasswordCredential)  java.security.AccessController
                .doPrivileged(new
    java.security.PrivilegedExceptionAction<oracle.security.jps.service.credstore.
    Credential>() { 
                 public
     oracle.security.jps.service.credstore.Credential run() throws Exception {
                  return (credStore .getCredential(mapName, csfKey));
                                }
                            });
                    } else {
                        // failure obtaining csf credentials
                    }
                }
            } catch (final java.security.PrivilegedActionException ex) {
                //handle excpetion
            } catch (final oracle.security.jps.JpsException jpse) {
                //handle excpetion
            }
            return passwordCredential;
        }
     
     
        private static oracle.security.jps.service.credstore.CredentialStore
     getCredStore() throws oracle.security.jps.JpsException {
            oracle.security.jps.service.credstore.CredentialStore csfStore;
            oracle.security.jps.service.credstore.CredentialStore appCsfStore = null;
            oracle.security.jps.service.credstore.CredentialStore systemCsfStore =
     null;
     
            final oracle.security.jps.internal.api.runtime.ServerContextFactory
     factory = (oracle.security.jps.internal.api.runtime.ServerContextFactory)
     oracle.security.jps.JpsContextFactory
                .getContextFactory();
     
            final oracle.security.jps.JpsContext jpsCtxSystemDefault =
     factory.getContext(oracle.security.jps.internal.api.runtime.ServerContextFactory.S
    cope.SYSTEM);
     
            final oracle.security.jps.JpsContext jpsCtxAppDefault = factory
                .getContext(oracle.security.jps.internal.api.runtime.ServerContextFactory.Scope.AP
    PLICATION);
     
            appCsfStore = (jpsCtxAppDefault != null) ? jpsCtxAppDefault
                .getServiceInstance(oracle.security.jps.service.credstore.CredentialStore.class) :
     null;
     
            if (appCsfStore == null) {
                systemCsfStore = jpsCtxSystemDefault
                    .getServiceInstance(oracle.security.jps.service.credstore.CredentialStore.class);
                csfStore = systemCsfStore;
            } else {
                //use Credential Store defined in app-level jps-config.xml
                csfStore = appCsfStore;
            }
            return csfStore;
        }
    

Note:

The following JAR files must be included in the classpath: oracle.jps_12.1.2/jps-api.jar, oracle.jps_12.1.2/jps-unsupported-api.jar.

You must provide the CredentialAccessPermission permission to the custom policy executor jar. For more information about granting permissions, see "Setting the Java Security Policy Permissions" in Securing Applications with Oracle Platform Security Services.

4.8 Handling Exceptions in Custom Assertions

You can handle exceptions in the custom assertion executor using the WSMException method.

For more information, see the following topics:

4.8.1 About WSMException Method

Any exceptions during the execution of custom assertions must be handled by the WSMException in the custom assertion executor.

IResult execute(IContext mcontext) throws WSMException

This method must always return a non-null IResult object. The status field indicates success or failure or other state. The IResult.getFault() method is used to return the detailed cause for failure and returns null in case of success.

4.8.2 Processing Exceptions in WSMException

The exceptions arising from within the execute method of custom assertion executor should first be wrapped in WSMException, the execution status should be set to IResult.FAILED, and the generateFault method throws the WSMException.

The following example shows this:

IResult execute(IContext mcontext) throws WSMException {
   IResult result = new Result();
   try {
      ....
      .....
 
   } catch (Exception e) {
      WSMException wsmException = new WSMException(e);
      result.setStatus(IResult.FAILED);
      generateFault(wsmException);
   }
}