Wednesday, June 24, 2009

WS security in OSB

In OSB you can protect your WSDL proxy services with XML Signature / encryption, authentication or your own custom ws-policy. In this blog entry I will give you all the information how to do this.
First we start by adding a standard OSB WS-Policy. Open the WSDL of a proxy service where we add for example the signing policy. We always need to add wsp:UsingPolicy element else OSB won't detect the wanted security policy

<?xml version="1.0" encoding="UTF-8"?>
<definitions targetNamespace=""
name="HelloWorldService" xmlns:soap=""
xmlns:tns="" xmlns:xsd=""
xmlns="" xmlns:wsp="">
<wsp:UsingPolicy wsdl:Required="true" xmlns:wsdl=""/>
<xsd:import namespace="" schemaLocation="Helloworld.xsd"/>

Add the Signing policy to a operation or put this in a other part of the WSDL see this url for more information. In this case I can use wsp:Policy with a PolicyReference and the URI is policy:Sign.xml . If you want encryption then you can use policy:Encrypt.xml as URI or use policy:Auth.xml for ws authentication. Off course you can combine policies.

<binding name="HelloWorldServiceSoapHttpPortBinding" type="tns:HelloWorldService">
<soap:binding transport="" style="document"/>
<operation name="sayHello">
<wsp:PolicyReference URI="policy:Sign.xml"/>

You don't have to use the OSB standard policies, you can also add your own ws-policy ( in OSB 10.3 you can only use the policy definition of WLS 9, so don't expect you can make policies which uses the 2005 or 2007 WS-Security standard). Here is a example of a custom policy.

<?xml version="1.0"?>
<wsp:Policy wsu:Id="X509v3"
<sp:RequireThumbprintReference />
<sp:WssX509V3Token10 />
<sp:RequireThumbprintReference />
<sp:WssX509V3Token10 />
<sp:TripleDesRsa15 />
<sp:Strict />
<sp:IncludeTimestamp />
<sp:OnlySignEntireHeadersAndBody />

The value of the wsu:Id attribute if important for the WS policy reference in the WSDL of the proxy service

<binding name="HelloWorldServiceSoapHttpPortBinding" type="tns:HelloWorldService">
<soap:binding transport="" style="document"/>
<operation name="sayHello">
<wsp:PolicyReference URI="policy:X509v3"/>

In this case the URI has policy:X509v3 as value

The next step is to make some keystores for WebLogic and OSB. We need to create 509 v3 certificates and import these certificates in a java 1.6 keystore for signing and encryption.
We need to have 509 version 3 certificates because we need the SubjectKeyIdentifier extension. This is only supported in version 3 of 509 and only OpenSSL can generate these certificates.

You can use self signed v3 certificates, for more info see this Glen Mazza's weblog. I'll use a CA.
#first make a CA request
C:\tools\OpenSSL\bin\openssl genrsa -des3 -out C:\projecten\certs2\ca.key 4096 -rand random
#self sign our CA certificate
C:\tools\OpenSSL\bin\\openssl req -new -x509 -days 3650 -config C:\projecten\certs2\ca.conf -key C:\projecten\certs2\ca.key -out C:\projecten\certs2\ca.crt

# make serial.txt file in C:\projecten\certs2\ and add 01 in this file

# make an empty index.txt file in C:\projecten\certs2\

Download the ca.conf which will be used to sign the certificates

# generate a server request and use servername with the domain name as common name CN
c:\tools\openssl\bin\openssl genrsa -des3 -out C:\projecten\certs2\server.key 4096
c:\tools\openssl\bin\openssl req -newkey rsa:1024 -nodes -keyout C:\projecten\certs2\server.key -out C:\projecten\certs2\server.csr -config C:\projecten\certs2\ca.conf

# sign the server request with your CA key
c:\tools\openssl\bin\openssl ca -in C:\projecten\certs2\server.csr -out C:\projecten\certs2\server.pem -keyfile C:\projecten\certs2\ca.key -cert c:\projecten\certs2\ca.crt -config C:\projecten\certs2\ca.conf

# export server
c:\tools\openssl\bin\openssl pkcs12 -export -inkey C:\projecten\certs2\server.key -in C:\projecten\certs2\server.pem -out C:\projecten\certs2\server.p12 -name server

C:\java\jdk160_05\bin\keytool -importkeystore -destkeystore C:\projecten\certs2\keystore.jks -deststorepass welcome -srckeystore C:\projecten\certs2\server.p12 -srcstorepass welcome -srcstoretype pkcs12
C:\java\jdk160_05\bin\keytool -list -keystore C:\projecten\certs2\keystore.jks -storepass welcome
C:\java\jdk160_05\bin\keytool -exportcert -alias server -storepass welcome -keystore C:\projecten\certs2\keystore.jks -file C:\projecten\certs2\server.cer
C:\java\jdk160_05\bin\keytool -printcert -file C:\projecten\certs2\server.cer

# generate client request
c:\tools\openssl\bin\openssl genrsa -des3 -out C:\projecten\certs2\client.key 4096
c:\tools\openssl\bin\openssl req -newkey rsa:1024 -nodes -keyout C:\projecten\certs2\client.key -out C:\projecten\certs2\client.csr -config C:\projecten\certs2\ca.conf

# sign client request
c:\tools\openssl\bin\openssl ca -in C:\projecten\certs2\client.csr -out C:\projecten\certs2\client.pem -keyfile C:\projecten\certs2\ca.key -cert c:\projecten\certs2\ca.crt -config C:\projecten\certs2\ca.conf

# export client
c:\tools\openssl\bin\openssl pkcs12 -export -inkey C:\projecten\certs2\client.key -in C:\projecten\certs2\client.pem -out C:\projecten\certs2\client.p12 -name client

C:\java\jdk160_05\bin\keytool -importkeystore -destkeystore C:\projecten\certs2\keystore.jks -deststorepass welcome -srckeystore C:\projecten\certs2\client.p12 -srcstorepass welcome -srcstoretype pkcs12
C:\java\jdk160_05\bin\keytool -list -keystore C:\projecten\certs2\keystore.jks -storepass welcome
C:\java\jdk160_05\bin\keytool -exportcert -alias client -storepass welcome -keystore C:\projecten\certs2\keystore.jks -file C:\projecten\certs2\client.cer
C:\java\jdk160_05\bin\keytool -printcert -file C:\projecten\certs2\client.cer

# make a truststore with the ca and the public keys
C:\java\jdk160_05\bin\keytool -import -file c:\projecten\certs2\ca.crt -alias ca -trustcacerts -keystore C:\projecten\certs2\trust.jks -storepass welcome -keypass welcome
C:\java\jdk160_05\bin\keytool -import -file C:\projecten\certs2\client.cer -alias client -keystore C:\projecten\certs2\trust.jks -storepass welcome -keypass welcome
C:\java\jdk160_05\bin\keytool -import -file C:\projecten\certs2\server.cer -alias server -keystore C:\projecten\certs2\trust.jks -storepass welcome -keypass welcome
C:\java\jdk160_05\bin\keytool -list -keystore C:\projecten\certs2\trust.jks -storepass welcome

The next step is to configure Weblogic. First we add the new keystores and configure SSL and add a new PKI Credential mapping provider. The PKI Credential mapping provider will be used by OSB for the XMLsignature and encryption. The trust keystore will be used to check if the signer certificate is trusted.
Go to the OSB server in the WLS console
In the keystore tab we will add our keystores

In the SSL tab we will use the server certificate which has the server + domain name as Common name so Internet explorer won't complain that the certificate and server name does not match.

Select the myrealm Security Realm where we will add a new PKI Credential Mapping provider

In the Providers tab we will create a new PKI Credential Mapping
Select the just created PKI credential mapping and fill the values in the Provider Specific tab. Use the keystore and not the trust keystore for this

We are finished in the Weblogic Console and we can go the OSB console where we have to create a new Service Key provider and configure the Proxy service so it uses this provider.

Create a new Service Key provider. This how it looks like in the Workshop but this does not work because eclipse can't retrieve the certificates of the PKI credential mapping provider.

So we have to use the OSB console to add the right certificate for signing and encryption to the Service Key Provider.
Now we see the certificates of the Weblogic PKI Credential mapping. If you don't see this then probably you don't use 509 version 3 certifcates.

The last step is to configure the proxy service. Here we have to disable XOP/MTOM support
And select the Service Key Provider

Now we can test the proxy service by invoking the WS and selecting the Service Key Provider.

With this as result

And this is how the WSDL with signing looks like

That's all.

If you want to use OSB 10.3 security with Soa Suite 11g R1 then you should read this 11g documentation, This explains how to change the OSB encrypt and sign policy so it works with FMW 11g.

Monday, June 15, 2009

OSB & ESB Performance comparison

With the release of OSB 1.3.1 with JCA adapter support I can finally compare the OSB with the ESB. I will run this performance test on my Dell laptop ( Core2Duo T9400 2.53 GHz with 3,5 Gb memory ) and try to use the same components in the OSB and the ESB. For example I will use a memory JMS Queue in the Oracle Application server as starting point for the ESB and a file based JMS Queue in WLS as starting point for the OSB process. Both OSB and ESB processes has to fill the same four tables in the Oracle 11G database and they will use the same Toplink database mappings.
For the test I will disable the JMS adapter in the ESB console or stop the queue consumption in the WLS console. Then fill the Queues and start the Service Bus processes . Before the test I will do some test runs so I know everything is alright and the Service Bus is warmed up.
Here is a picture of the ESB process. This process reads the Queue and pass it asynchronous to the next Router. This message with a XML anytype element is transformed with XSLT to a specific message schema and the last Router transforms it to the database adapter XSD.

The OSB process works almost the same as the ESB process but in the OSB I will use XQuery instead of XLST and use Proxy Services as Routers and a Business service as Database Adapter.
Here you see a process schema of Messaging proxy service. It start with a PipelinePair to do some XSD validation on the incoming message. Then the Proxy Service determines the message type in in the RouteNode, do the first XQuery transformation to make the specific message XML and start the next specific Message Proxy Service.

The specific message Proxy Service validates the XML and in the RouteNode ( Mapped to the JCA database adapter Business Service ) the next XQuery takes place, so the Business Service get the right XML for the Toplink database mapping.

Here are my test results
OSB 10.3.1 with JRocket JVM

Total MessagesSize Message in KBTime in Seconds
With validation
Time in Seconds


Total MessagesSize Message in KBTime in Seconds
With validation
Time in Seconds


The OSB is the overall winner with 15% a 90% better performance than the ESB. Off course this is not the best testcase and there are other areas of the Service Bus where you can do tests for, but with this case the OSB is much faster especially with big messages ( even with JRockit ) . This OSB process does even more then the ESB process, the OSB process returns a message with the result of the database adapter and put this message in a WLS Queue.
Don't know why OSB has a better performance, maybe Weblogic is faster or the ESB instance logging is the problem. In the next Soa Suite patchset, I can test the ESB processes on WebLogic server and compare this with these results.

Thursday, June 11, 2009

Using AQ in an OSB 10.3.1 Proxy Service

In my previous blogpost I already showed you how to use a JCA Database adapter in a Business Service. In this blog I will use the AQ resource adapter in a OSB 10.3.1 Proxy Service. To make this work I use the Oracle Workshop for the OSB configuration and JDeveloper for AQ adapter configuration. I heard from Oracle that in one of the next 11g releases you can do this all in JDeveloper.
We start in the WLS console of the OSB Server. Go to the deployments and find the AqAdapter resource adapter.
Open the AqAdapter and select the configuration Tab where we will create a new outbound connection pool.
Provide the JNDI name, I'll use the JDeveloper name convention. eis/AQ/xxxx , xxxx is the database connection name in JDeveloper.

Give the resource adapter plan a unique name and save this AQ plan.

Select the just created JDNI configuration.

We have provide the xADatasourceName. This is a datasource of WLS which connects to a Oracle schema user which has access to the AQ queues. Or you can provide the jdbc url , username and password.

We are finished with the Weblogic configuration and we can switch to JDeveloper where we will make the AQ configuration files which we have to import in our OSB project.
Make a new ESB project where we will add the AQ adapter to the ESB configuration. The JNDI name in the AQ adapter wizard must match with the JNDI eis name of the AQ resource adapter in the WLS console.

This OSB proxy service read from the queue so we need to dequeue.

Browse or provide the schema /queue name

And select a XSD which matches with the AQ messages.

Delete the router service we don't need this.

The last part is to use this AQ queue in a OSB proxy service, Start the Oracle workshop and import AQ wsdl's and schema's into your OSB project.

Create a new Proxy service and use the AQ WSDL. OSB will detect the JCA adapter configuration.

Now we only have to provide the JNDI name in my case eis/AQ/xxxxx
That's all for the AQ configuration.

Tuesday, June 9, 2009

OSB 10.3.1 with Database adapter

With the OSB 10.3.1 release we can use the JCA Database adapter in our processes. In this blog I will show you, what steps are needed to make this work.
First we need to create a XA thin JDBC datasource in the WLS console of the OSB Server.
Next step is to configure the DB resource adapter. Go to deployments in the WLS Console of the OSB Server, where we select the DbAdapter deployment.

Go to Outbound Connection Pools Tab under Configuration and select the already created connectionfactory and press New.
Select the ConnectionFactory
The JNDI Name is the same as the EIS name which you need to provide in the DB adapter service. ( We will do this in JDeveloper ) . In my case eis/DB/xxxxx

Now we only have to provide the XAdatasource with as value the just created datasource
Restart the OSB server.

Switch to JDeveloper where we will create a new ESB project. ( I will create a new ESB Project for every DB adapter, This will make deployment a little bit easier). Add a new DB adapter in the ESB overview.

Now we have to provide the EIS jndi name, this must match with the JNDI EIS name in the DB resource adapter configuration ( which we created in the WLS console on the OSB server)

Complete the DB adapter configuration

We need this WSDL in the OSB, This WSDL contains the EIS JNDI name and the wanted operation.

We need the toplink classes in the OSB server so we need to make a jar deployment profile.

Start the Oracle Workshop where we make a new folder (with the name of the DB adapter service) in your project. Import the jar and the WSDL's / XSD of the JDeveloper ESB project.
Create a new Business Service and use the WSDL of your DB adapter service.

Provide the JCA name, in my case jca://eis/DB/xxxxx

In the JCS Transport Configuration Tab we only need to add the toplink_mapping.xml ( Do this add the toplink xml section)
Deploy the project to the OSB Server.
Last step is to test the Business Service with a valid xml.

check for errors in the WLS Console output window.

Monday, June 8, 2009

Oracle Service Bus 10.3.1 with AQ & DB adapter support

Oracle has released OSB 10.3.1, This version has a JCA transport support, so now you can use the Oracle Apps, Advanced Queuing (AQ) or the Database adapters in OSB, just like you can in the Soa Suite. It also support WSLT import & export of OSB configurations, possible very handy for automatically publishing. And the latest Enterprise Grid Control release can monitor your Weblogic server and OSB service.

Here some handy information about the OSB 10.3.1 release.

Friday, June 5, 2009

Passing WS-Security credentials in Oracle ESB 10.1.3

In Soa Suite 10.1.3 you can use OWSM to add WS-Security credentials to your outgoing SOAP calls. If you don't have OWSM installed or don't want to use it, then you can also do this in the XSLT of a ESB Routing Service. We can use the SOAP header XSLT function to achieve this. See this blog of Dharmendra Dubey for a description. This is only works in Soa Suite, when you have installed then you need to an extra /Header element to xpath expression like this
<xsl:variable name="setUsername"
My solution is a bit different, I made a custom XSLT function which can add WS-Security credentials and add a Timestamp to the SOAP Header. You only have to provide the username, password , digest ( or plaintext ) and the time ( in ms ) this SOAP message is valid.
Just add this function to the XSLT of the Routing Service <xsl:variable name="securityHeader" select="customESBFunctions:setUsernameToken('weblogic','weblogic',false,100)"/>
This is how my XSLT looks like.

<xsl:stylesheet version="1.0"
exclude-result-prefixes="xsl tns s0 xsd soap wsp bpws customESBFunctions ehdr hwf xp20 xref ora ids orcl">

<xsl:variable name="securityHeader" select="customESBFunctions:setUsernameToken('weblogic','weblogic',false,100)"/>

<xsl:template match="/">
<xsl:value-of select="/tns:sayHello"/>

And with this as result.

<soapenv:Envelope xmlns:soapenv="">
<soap:Header xmlns:soap="">
<wsse:Security xmlns:wsse=""
<wsu:Timestamp xmlns:wsu=""
<wsse:Password Type="">65szVNxFtj2EVicUi3ePTD1UgxE=</wsse:Password>
<soapenv:Body xmlns:wsu=""
<saml:sayHello xmlns:saml=""></saml:sayHello>

This is my java source for the xslt function.

package nl.whitehorses.esb.xslt.functions.headers;




import java.text.SimpleDateFormat;

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import oracle.tip.esb.server.headers.ESBHeaderContext;

import org.w3c.dom.Element;
import org.w3c.dom.Document;
import oracle.xml.parser.v2.XMLDocument;
import org.xml.sax.SAXException;

public class ESBCustomFunctions {

public static String getHeader() throws IOException {
Element requestHeader = ESBHeaderContext.getRequestHeader();
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
return sw.toString();

public static String setUsernameToken(String user,String password,Boolean digest, Double valid)
throws IOException, SAXException, ParserConfigurationException {
long currentTime = System.currentTimeMillis();
SimpleDateFormat calendarFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
TimeZone utc = TimeZone.getTimeZone("UTC");
Calendar calendar = new GregorianCalendar(utc);

String createTime = calendarFormatter.format(calendar.getTime());
if ( valid != null ) calendar.setTimeInMillis(currentTime + valid.longValue());
String expiresTime = calendarFormatter.format(calendar.getTime());

String securityHeader =
"<wsse:Security xmlns:wsse=\"\"" +
" xmlns:soapenv=\"\" soapenv:mustUnderstand=\"1\">" +
" <wsu:Timestamp xmlns:wsu=\"\"" +
" wsu:Id=\"wsTime\">" +
" <wsu:Created>"+createTime+"</wsu:Created>" +
" <wsu:Expires>"+expiresTime+"</wsu:Expires>" +
" </wsu:Timestamp>" +
" <wsse:UsernameToken>" +
" <wsse:Username>"+user+"</wsse:Username>" ;
if ( digest ) {
securityHeader = securityHeader+ " <wsse:Password Type=\"\">"+ passwordDigest( password)+"</wsse:Password>";
} else {
securityHeader = securityHeader+ " <wsse:Password Type=\"\">"+password+"</wsse:Password>" ;
securityHeader = securityHeader +
" </wsse:UsernameToken>" +

Element outboundHeader = null;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Document doc = factory.newDocumentBuilder().parse(new ByteArrayInputStream(securityHeader.getBytes()));
outboundHeader = (Element)doc.getFirstChild();
return securityHeader;

private static String passwordDigest(String password) {
String utf8String = (new StringBuilder()).append(password).toString();
byte utf8Bytes[] = null;
try {
utf8Bytes = utf8String.getBytes("utf-8");
catch(UnsupportedEncodingException uee) {
byte bytesToHash[] = utf8Bytes;
byte hash[] =null;
try {
MessageDigest sha = MessageDigest.getInstance("SHA-1");
hash = sha.digest(bytesToHash);
catch(Exception e) {
return Base64.encode(hash);

public static void main(String[] args) throws Exception {
System.out.println( setUsernameToken("weblogic","weblogic",true, null));


And custom extension definitions for JDeveloper with the new XSLT function.

<?xml version="1.0" encoding="UTF-8"?>
<functions xmlns:customESBFunctions="">

<function name="customESBFunctions:getHeader" as="string">

<function name="customESBFunctions:setUsernameToken" as="string">
<param name="user" as="string"/>
<param name="password" as="string"/>
<param name="digest" as="boolean"/>
<param name="valid" as="number"/>


See my previous blogpost for the deployment details

Monday, June 1, 2009

Using Weblogic 10.3 Queues & Topics in Soa Suite

If you follow this great guide of Pavan. you can use the JMS Queues / Topics of Weblogic 9.2 in In Soa Suite / But I don't want to do a step back and want to use the Weblogic 10.3 version. With the help of Oracle Support it works now with version 10.3. The only thing I had to change ( if you follow the Pavan Guide ) is to remove the weblogic jar from the jms adapter folder in the Soa Suite J2EE container.
Generate a jdk5 wsfullclient jar and put this in a folder where Soa Suite does not automatically loads this jar. Change the server.xml of the Soa Suite Container where we will add this jar to oracle.bpel.common shared library. Make sure the fullclient reference is before orabpel-thirdparty.jar reference, because this thirdparty also contains wls classes.

<shared-library name="oracle.bpel.common" version="10.1.3">
<code-source path="C:\oracle\prodcuct\10.1.3\soaas_1/bpel/system/classes"/>
<code-source path="C:/java/wlfullclient5.jar"/>
<code-source path="C:\oracle\prodcuct\10.1.3\soaas_1/bpel/lib/orabpel-common.jar"/>
<code-source path="C:\oracle\prodcuct\10.1.3\soaas_1/bpel/lib/orabpel-thirdparty.jar"/>
<code-source path="C:\oracle\prodcuct\10.1.3\soaas_1/bpel/lib/orabpel.jar"/>

Or you can wait for the MLR8 patch.
Now we can use the WLS 10.3 JMS adapters in Oracle BPEL and ESB.