A recent white paper by Marc Chanliau, Oracle Fusion Middleware Product Management, on Web Services Security is now available on OTN. The What is required to secure SOA white paper gives a clear overview of the security requirements for services and how these requirements, with corresponding ‘standards’, have evolved.
In his paper, Marc discusses transport layer as well as application layer security for services. He also outlines the role of the many security related standards, technologies and tools out there. The approach taken shows how and where they compliment or overlap. Such topics include:
Confidentiality, Integrity, Authenticity: XML Encryption, XML Signature.
Every web services developer should have an understanding of these concepts. I highly recommend this document as a basic primer in web services security.
Within the past week the 3rd technology preview of JDeveloper 11g was made available on the Oracle Technology Network (OTN) website. For me, the most significant aspect of this preview is that it includes a preview of the long awaited SOA Suite 11g which supports the Service Component Architecture (SCA) specification. This Technology Preview release of Oracle SOA Suite 11g showcases the support for SCA through the new composite assembly editor in JDeveloper as well as a unified service engine foundation for the full set of SOA Suite components.
The SOA Suite 11g software is available within the JDeveloper 11g environment – yes, that’s right! You only install JDeveloper and you also get the SOA Suite server side for deploying your 11g composite applications!
Web service handlers are not a new concept. One obvious issue with developing a web service is catering for common behaviour. If each operation requires the same set of services, such as security or logging, how do you provide those services? A web service handler is the solution for both common client-side as well as server-side behaviour. Handlers allow you to process SOAP messages before and after the message is sent through the network.
Web service handlers are a part of the JAX-RPC specification, and the JAX-WS specification caters for the same concept, but in a slightly different way. There are some handler examples on the net but most just deal with logging the request and response. This article will introduce something a bit more complicated, putting a Software As A Service handler on the Dice web service. For an overview of JAX-WS handler infrastructure, as well as the difference between SOAPHandler and LogicalHandler see the excellent Handlers Introduction on java.net.
In this Dice SAAS example JDeveloper 11g Technology Preview 2 is used. It supports JAX-WS and has an embedded OC4J server for running the web service. To get started, download the Dice project, which is ready to go with the annotated web service code and add it to your JDev workspace. Details about the Dice web service and how it is constructed can be found in a previous article.
The first thing to do is test that the web service works in your environment. To do this launch the Test Web Service utility by right clicking on the Dice web service in the Application Navigator.
This will start the embedded OC4J server, deploy the web service and launch the HTTP Analyzer with the WSDL for the Dice web service loaded. In the SOAP Structure panel enter a number of sides for the Die and press the Send Request button. Of course you can choose to add more Die by clicking on the + symbol beside the die: Array, or editing the request in the HTTP Content panel.
After pressing the Send Request button you should see the response showing each Die and their value after rolling.
Once you have that working you can move on to writing a handler class and configure the web service to use it. In this example, the SOAP handler class will use resource injection (i.e. @Resource annotation and environment entry elements) for initialisation parameters rather than using the init-params element in the deployment descriptor. This is a little emphasised difference between JAX-RPC and JAX-WS.
There is one more download to get for this example, the handler class and the handler chain descriptor which refers to it. A handler chain defines a set of handlers that should be used for the web service. The web service implementation will have an annotation stating where the handler chain descriptor file is. Extract these two files to the project. To use them add the following to the Dice.java, just after the @WebService annotation:
Note that you will need to import javax.jws.HandlerChain.
The SaaSServerHandler class in this case checks that the calling client is allowed to invoke the web service by looking in the SOAP header for a ‘key’ element with a namespace of urn:soastation:saas. It will also check that the value matches a ‘ValidKeyValue’ environment entry in the web app deployment descriptor. You could further modify the handler to only allow a single Die element in the SOAP envelope if no valid key is provided. That is, a client with the key can use multiple Die while a client without, such as a guest or demonstration client can only use one. Alternatively you could keep track of registered keys and usage. The software as a service options are endless.
Back to the example, looking at the SaaSServerHandler the handleMessage method checks if the message is inbound (request coming in) or outbound (response going out). If the handler was being used for a web service client the outbound message would be the request being sent and the inbound message would be the response beng received. In our example we are interested in the inbound message because we are expecting a particular element. Note that the handler class has a instance variable called saasKeyValue which is set be the ‘ValidKeyValue’ environment entry. To set this, edit the web.xml and add the following:
eValidKeyValue java.lang.String soastation
Test the web service as before. You should get the following fault:
javax.xml.ws.WebServiceException: Invalid service key in SOAP Header. Expecting {urn:soastation:saas}key
Now test it again, but add the required element to the SOAP header. To do this edit the request in the HTTP Content tab. The request should look like this:
soastation
The corresponding result should be the same as when you originally tested the web service before adding the handler. If so, you have successfully implemented the soap handler.
This article discussed how to implement a server side JAX-WS SOAP Handler using the second technology preview of JDeveloper. It has provided code examples of how the handler concept work, including externalising properties in the environment entry elements. Also mentioned were ideas for further development such as reducing the capabilities for ‘guest’ clients. There really is a lot one can do with web service handlers.
At last! A software development manifesto for all of us! Martha Stewart provides some top tips for success in the Autumn edition of wired magazine’s How To Guide. Now, whether you are Agile, Extreme, or recovering from COBOL Fingers you can huddle with the masses under the ‘Making things go faster – but not worse’ banner.
Of course Martha is not a patch on The Toilet Roll Lady who inspired a whole generation of scientists, engineers and public relation gurus. Yes folks, Mary ‘Make and Do’ has a DVD out to capture the nostalgia of yesteryear. Ideal Christmas present for the toilet roll collector in your family.
A couple of weeks back some colleagues working on a POC came across this runtime error when invoking a web service through a generated web service proxy client:
trailing block elements must have an id attribute
This exception was being thrown within the web service proxy client when parsing the response from the web service. Using HttpAnalyzer in JDeveloper (versions 10.1.3.1 & 10.1.3.2 were used) we could see that the request was being sent and a response was being received, so clearly nothing wrong with the web service being invoked. Or so we thought…
It turned out that the published WSDL & XSD and the web service implementation were not matching. The XSD for an element in the response said that Address had a maxOccurs=”1″ however, the web service implementation was returning multiple Address elements. The web service proxy client is generated from the WSDL & XSD so it is only expecting one Address element in the response stream, hence the error at runtime.
We had to double check which was correct, and a quick check through documentation showed that the schema had not been updated when the object model had changed. Once that was determined, it was straight forward to correct the schema entry, maxOccurs=”unbounded”, and regenerate the web service proxy client.
So, if you get this obscure ‘trailing block elements must have an id attribute’ error message at runtime double check that the published interfaces (WSDL & XSD) match the implementation.