Tuesday, July 13, 2010

Intel SOA Expressway Service Gateway and WebLogic 11g Application server message exchange with SignatureConfirmation

Intel SOA Expressway is often used as a security gateway in B2B or app-to-app integration scenarios. Therefore Intel SOA Expressway has to interoperate with different WSDL/WS-Policy/WS-Security capabilities of ESBs and Application Servers. In this writeup I am going to discuss SOAE's security interoperability with Oracle 11g Application Server

Both Oracle WebLogic and Intel SOA Expressway support an extensive set of WS-Security standards, in this post I'll show how to make Oracle WebLogic produce messages with signature confirmations and how to make Intel SOA Expressway validate signature confirmations. We'll create a web-service application for WebLogic and configure security gateway application for Intel SOA Expressway.

Let's start with WebLogic, it supports JSR-181 and extends it with some weblogic-specific annotations.
/* file - src/wl/example/Hello.java */
package wl.example;
import javax.jws.*;
import weblogic.jws.Policy;

@WebService
@Policy(uri="wspolicy.xml")
public class Hello {
@WebMethod
public String world(String s) {
return "Hello " + s + " I hear you!";
}
}


Service logic is contained in the java source above but security is offloaded into the Policy file 'wspolicy.xml' listed below.


<!-- file src/wl/example/wspolicy.xml -->
<wsp:Policy
xmlns:s0="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<sp:AsymmetricBinding
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<sp:InitiatorToken>
<wsp:Policy>
<sp:X509Token
sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:WssX509V3Token11/>
</wsp:Policy>
</sp:X509Token>
</wsp:Policy>
</sp:InitiatorToken>
<sp:RecipientToken>
<wsp:Policy>
<sp:X509Token
sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never">
<wsp:Policy>
<sp:WssX509V3Token11/>
</wsp:Policy>
</sp:X509Token>
</wsp:Policy>
</sp:RecipientToken>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:TripleDesRsa15/>
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:Layout>
<wsp:Policy>
<sp:Lax/>
</wsp:Policy>
</sp:Layout>
<sp:IncludeTimestamp/>
<sp:OnlySignEntireHeadersAndBody/>
</wsp:Policy>
</sp:AsymmetricBinding>
<sp:Wss11 xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<sp:MustSupportRefKeyIdentifier/>
<sp:MustSupportRefIssuerSerial/>
<sp:RequireSignatureConfirmation/>
</wsp:Policy>
</sp:Wss11>
</wsp:Policy>


The policy is pretty simple, it forces both ends to sign messages and to use signature confirmations.

Here is build.xml to build the deploy-able war-file for weblogic
<!-- file build.xml -->
<project name="webservice" default='compile'>
<property name='src' value='src'/>
<property name='bin' value='bin'/>
<property name='wl-server-lib' value='../lib'/>
<path id='web-logic'>
<pathelement
location="${wl-server-lib}/weblogic.jar"/>
<pathelement
location="${wl-server-lib}/wls-api.jar"/>
<pathelement
location="${wl-server-lib}/wlclient.jar"/>
<pathelement
location="${wl-server-lib}/desc.jar"/>
<pathelement
location="${wl-server-lib}/com.bea.core.xml.beaxmlbeans_2.2.0.0.jar"/>
<pathelement
location="${wl-server-lib}/com.bea.core.xml.staxb.runtime_1.0.0.0.jar"/>
<pathelement location="${wl-server-lib}/com.bea.core.annogen_1.0.0.0.jar"/>
</path>

<taskdef name="jwsc" classpathref='web-logic'
classname="weblogic.wsee.tools.anttasks.JwscTask"/>
<target name="prepare">
<mkdir dir='${bin}'/>
</target>

<target name="compile" depends='prepare'>
<jwsc srcdir='${src}' destdir='${bin}'>
<jws file='wl/example/Hello.java'/>
</jwsc>
</target>

<target name="clean">
<delete dir='${bin}'/>
</target>
</project>


Key-pair and certificate installation process for weblogic is described here.

After compilation and deployment the web-service WSDL will be available at url http://weblogic:weblogic_port/Hello/Hello?WSDL. For further imports we will save this wsdl into a file 'hello.wsdl'.

WebLogic web-service is up and running now, we have the wsdl saved into file, so we are ready to create an Intel SOA Expressway proxy application.

First, create a new Empty SOAE Project in Intel Services Designed. In the empty project, create a new Workflow using template "Web Services proxy SOAE Workflow".


Pass hello.wsdl to the service proxy creation wizard

and click the "Finish" button. The proxy application is ready now, but it doesn't do any security governance. Our application needs to:

  • sign messages before sending them to WebLogic service

  • verify signatures in WebLogic responses

  • verify signature confirmations of WebLogic responses


We need to create a separate ws policy for each of these activities.


First we will create a policy with the name "sign" and operation type "Sign". The wspolicy.xml declares the TripleDesRsa15 algorithm suite, which means we should use the rsaWithSha1 signature generation method and sha1 digest generation method. The X509 key-pair token name should be specified for the sign operation ('client' for example). We also need to set "Save signature confirmation data" checkbox to use this data later, for signature confirmation.


Second operation in the order of the application is Verify. Create a policy with the name "verify_signature" and operation type "Verify". Verification should use the same set of algorithms as signing, but it's important to use a Certificate from the security configuration with the name 'server' and to specify web service authentication policy which will control the verification process.



The last and the the most simple policy is the signature verification policy. Create a ws-security policy with the name 'verify_confirmation' and operation type 'Verify Signature Confirmations'.


Policies are ready now and we can apply them to the request and response of the Invoke activity.


Proxy workflow is complete. We can deploy it in Intel SOA Expressway.
In the Intel SOA Expressway management Console, we create a new configuration and security package. In the security package, we deploy a client key-pair, server certificate and certificate authority (ca) and create a Web Service Authentication policy with name 'proxy_policy' referring to the trusted ca group 'ca'.

Deploy the application into the application configuration and assign the security package to the uploaded application. Activate configuration. The proxy application is started now. We can send test request to check workflow functionality.

WebLogic will refuse a non-signed request.

$ curl -v --data-binary @req -H 'content-type: text/xml' http://weblogic:7003/Hello/Hello
* About to connect() to weblogic port 7003
* Trying 10.125.133.78... connected
* Connected to weblogic (10.125.133.78) port 7003
> POST /Hello/Hello HTTP/1.1
> User-Agent: curl/7.15.5 (i386-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
> Host: client_host:7003
> Accept: */*
> content-type: text/xml
> Content-Length: 183
>
> <SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
> <SOAP:Body>
> <ns2:world xmlns:ns2="http://wl/example">
> <ns2:s>test</ns2:s>
> </ns2:world>
> </SOAP:Body>
> </SOAP:Envelope>
>
< HTTP/1.1 500 Internal Server Error
< Date: Wed, 14 Jul 2010 08:46:53 GMT
< Transfer-Encoding: chunked
< Content-Type: text/xml; charset=utf-8
< X-Powered-By: Servlet/2.5 JSP/2.1
* Connection #0 to host weblogic left intact
* Closing connection #0
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header/>
<env:Body>
<env:Fault xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<faultcode>wsse:InvalidSecurity</faultcode>
<faultstring>
No id attribute on element http://schemas.xmlsoap.org/soap/envelope/:Body
</faultstring>
</env:Fault>
</env:Body>
</env:Envelope>


But SOAE will accept plain request, sign it and forward to weblogic, receive response verify it and send plain response back to client.


$ curl -v --data-binary @req -H 'content-type: text/xml' http://soae_server:7003/Hello/Hello
* About to connect() to soae_server port 7003
* Trying 10.125.133.17... connected
* Connected to soae_server (10.125.133.17) port 7003
> POST /Hello/Hello HTTP/1.1
> User-Agent: curl/7.15.5 (i386-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
> Host: client_host:7003
> Accept: */*
> content-type: text/xml
> Content-Length: 183
>
> <SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
> <SOAP:Body>
> <ns2:world xmlns:ns2="http://wl/example">
> <ns2:s>test</ns2:s>
> </ns2:world>
> </SOAP:Body></SOAP:Envelope>
>
< HTTP/1.1 200 OK
< Content-Type: text/xml;charset=utf-8
< Content-Length: 534
<?xml version="1.0" encoding="utf-8"?>
Connection #0 to host pblcbrxw028 left intact
* Closing connection #0
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Body wsu:Id="Body_HytYHeKjNiBvJUva">
<m:worldResponse xmlns:m="http://wl/example">
<m:return>Hello test I hear you!</m:return>
</m:worldResponse>
</env:Body>
</env:Envelope>