The intent of this document is to describe a functional implementation of a SOAP to CORBA bridge. This document aims to explain the design decisions made, the limitations inherent to the chosen solution and also intends to propose these solutions as a working standard for using SOAP as an accessing method of already established distributed services, using CORBA as a case study.
As of version 2 of the SoapBridge, we also support the inverse operation. By creating a CORBA IDL description of an established SOAP service, one can deploy CORBA clients to invoke such a service by using the SoapBridge as a gateway.
This document is intended for the use of developers and application designers alike that are conversant and involved with using XML and/or SOAP for accessing distributed services. This document will not attempt to explain or discuss any issues concerning the XML, SOAP, CORBA and/or the use of distributed services in itself but will instead assume that the reader possesses the required background knowledge.
As stated in the various documents regarding the SOAP protocol, SOAP is not intended as a replacement for CORBA or indeed any other form of distributed service processing. Instead it only specifies a Remote Procedure Call (RPC) mechanism using XML as the method for encoding the data to be transported for the call and an arbitrary transport method (most commonly HTTP) for communicating both the request and the response that together constitute the Remote Procedure Call.
Therefore we found it useful to consider the possibility of building a SOAP to CORBA bridge that would accept SOAP requests, forward them to established or new CORBA based servers and return the result as a SOAP response.
As of version 2 of the SoapBridge, we have also implemented the reverse procedure.
This document will describe the resulting design of this SOAP to CORBA bridge. The implementation is available as Open Source under the GPL license.
Brief description of how a SOAP call is handled by the bridge.
The incoming SOAP call is parsed and stored in a DOM. In our implementation the XERCES DOM parser is used for this purpose.
The SOAP bridge has access to the CORBA Interface Repository and the relevant method execution information is obtained from there. An attempt is made to match the information in the stored SOAP call to the interfaces found in the repository based on the SOAP action and the topmost element of the SOAP body.
If a match is found the data from the SOAP request is entered into a dynamic CORBA request that is build according to the interface specification for the requested method.
Again using the SOAP action, an instance of the desired service is looked up by using the CORBA Name Service. The request is dispatched using the CORBA dynamic invocation of the object found and the result, if any, is stored in a recursive structure.
Finally the SOAP response is formatted using the received data from the CORBA call and again the type and structure information found in the Interface Repository and returned to the caller.
Phase 1: Handling the incoming SOAP request.
The XML formatted SOAP request must undergo several transformations before it is suitable for submission to a distributed service as supplied by the CORBA mechanism.
The XML parser is responsible for checking that the XML document is well formed and in other respects compliant with the relevant specifications.
SOAP XML may contain references to other parts of itself, by specifiying a HREF and an ID attribute. A map is build of these references by traversing the DOM. This map is used to substitute the refered-to element in place of the refering element when the values are interpreted. See HrefIdMap::RealNode().
Phase 2: Matching the SOAP request to a CORBA service.
The next phase is to assign the data from the SOAP request to a collection of dynamic and recursive CORBA structures. For each "in" or "inout" parameter of the requested method we must construct one of these structures (the CORBA Dynamic Any structure).
This phase is accomplished by traversing the DOM while simultaneously descending down the corresponding Interface Repository information for the requested method. Each time we find a matching element we shift its value into the relevant CORBA Dynamic Any.
During this phase we also check for any user supplied type conversions and apply them.
Note: As SOAP allows the omission of the type specifiers when the underlying mechanism is already aware of the types involved, which is certainly the case here, we pay little to no attention to the types specified in the SOAP as long as we can succesfully convert the value.
Any difficulties encountered in this phase will generate a SOAP fault which is returned to the caller.
Phase 3: Invoking the CORBA service.
We are now ready to invoke the CORBA service. We once more descend down the interface repository description and build a dynamic request structure that we finally submit to the CORBA ORB.
Note: There is an evident redundancy involved in phases 2 and 3. However, this is intentional as it conceivably creates the possibility to split up the process over multiple threads or even multiple processes. The idea is that phase 3 will most likely block for some time while performing the actual request. In the interest of scalability we therefore loosely coupled the parsing and execution phases.
Phase 4: Returning the result.
Unless we have aborted somewhere in the earlier phases due to some kind of processing problem we now have the answer for the client. All that remains is to transform the CORBA "ANY" structures we received to a SOAP response.
Again, we apply the user-specified type conversions where applicable.
The client perspective of a SOAP to CORBA bridge.
The entire contents of any SOAP call follows directly from the CORBA IDL describing the service interface. This actually makes it possible to generate "skeleton" SOAP documents of both the SOAP request and the response. A client implementation could load such a "skeleton" document in a DOM, fill in the required data, transmit the request and receive exactly the expected response.
There are however a few issues to consider.
First of all, SOAP does not define sequences in the same way as CORBA does. Therefore there exists no 1:1 mapping in this case.
Specifically, the SOAP client might transmit the sequence as an array. This is acceptable and even advantageous as far as the bridge is concerned, as it would allow pre-allocating the corresponding CORBA sequence type.
However, CORBA also defines both bound sequence and arrays types which would be a much more logical target for the SOAP array type. Actually, the bridge SHOULD enforce this and SHOULD NOT accept an unbound sequence (what SOAP calls a "generic compound type") where the CORBA IDL specifies either a bound sequence or array type.
On the other hand, it is usually perfectly acceptable to submit the elements of an unbound sequence as simply a repeating list of XML elements, either complex or simple. The start and end elements of the enclosing parameter element will provide the sequence's boundaries.
The next issues are raised by the CORBA object references. These could in fact be simply transformed into a stringified IOR and transmitted back to the client for future calls. However this poses two rather unacceptable problems.
For security reasons, exposing the actual CORBA reference to the client as a stringified might transfer information we do not want the client to possess. Specifically it could expose the actual network addresses of the CORBA server, which might not be desirable. It could also expose information embedded in the object reference by the object instance, like database access information or other sensitive information.
Another, somewhat less important, problem with the stringified IOR is its length. These can and often do consist of several KB's of data, which is a lot for simply passing a handle to an object instance back and forth.
To overcome these issues we have defined a "context", administered at the server side, in which object references are kept. A specific CORBA server manages these contexts for the SOAP bridge clients.
A client that wishes to communicate with a CORBA server that returns object references is therefore REQUIRED to first establish a context with the context manager. At the client side this will be represented by a printable string of exactly seven characters.
Once a context has been established, any returned object references will be translated by the SOAP bridge as relative indices of the client's context. In turn, the client specifies an object reference in any call to the SOAP bridge as the returned context key suffixed with the relative object reference index. Contexts are established with a timeout value to the last time the have been accessed. The context manager will automatically destroy the context if the timeout expires.
We have looked at WSDL and found it unsuitable for our purposes in its current form. Our main objections are the complexity of the call descriptions and the lack of proper production level, platform and language independent code generators.
Moreover, we are looking at CORBA anyway so why not use the excellent description methods offered by CORBA IDL instead.
This has been implemented in version 2 of the SoapBridge and works as follows.
We will use the included ServerTime sample server to illustrate this. Here is the IDL for the service:
module ServerTime { interface Time { readonly attribute long Now; attribute long Drift; void WaitThisLong (in long seconds); }; };
Using any ORB vendor's IDL-to-code translator for your favorite language or platform you will have ready-to-use code for calling the described services.
The next step is to actually invoke the (SOAP based) service. The SoapBridge offers a special CORBA service for this bootstrapping problem:
interface CORBACall { attribute string contextKey; Object CreateSession (in string soapAddress, in string intfName, in boolean obtainContextKey, in CORBACallback cb); void DestroySession (in Object sessionObject); };
See the relevant IDL documentation at SOAPBridge::CORBACall for more details.
Several security issues have already been addressed in the sections above. In this chapter we will repeat these and other security issues, indicate possible pitfalls and attempt to address them.
The first obvious security issue is the simple fact that we are in fact making services available to the public at large that might never have been designed for that purpose. After all, the most obvious reason one would want to deploy a SOAP to CORBA bridge is for the purpose of making legacy services available to a larger public. For the sake of the argument we will highlight a few of the myriad of possible reasons to deploy such a bridge and discuss the possible problems that might arise.
Example of Intranet deployment.
A corporation wishes the make the database at its headquarters available to its branch offices using Intranet technology.
Apart from the evident security issues involved with this decision, like wiretapping or break-in attempts, which we'll assume are handled by the Intranet or VPN services installed, deploying a SOAP to CORBA bridge adds a few additional security issues.
Where the legacy CORBA services used binary transmission for its data, we've now made the data human readable. Although this simple translation does not in fact expose anything new, in practice it enlarges the number of potential attackers substantially as literally anybody can now capture, read, print out and/or retransmit the information using simple and readily available desktop tools, amongst which the Internet browser itself.
Unfortunately there is no obvious solution to this problem. If a corporation relies on its employee's inability to make screen dumps of displayed data in the first place, deploying a SOAP to CORBA bridge just aggravates an already existing problem rather than creating a new one.
A similar issue is raised by the possibly extended lifecycle of the services. Conceivably, the legacy system was designed to have a lifecycle where the user would logon, retrieve the desired information and logout, all in rapid successive calls over the local area network. If we translate such a scenario to one where the user fills in a form with the logon information and performs the SOAP call to do the logon, then types the query in a second form and retrieves the information and finally has to click a button to issue the SOAP call that will perform the logoff, one can see we've added quite a potential for performing "man in the middle" attacks.
Yet again this problem is inherent with the design of the original system and no new issues have been raised.
In short, if common security measures are deployed, using SOAP to CORBA translation raises no new security problems in the case of an Intranet scenario. Existing security issues (imperfections) might however be aggravated to an unacceptable extend.
Example of Internet deployment.
A corporation wishes to publish information, for instance articles from a catalog, on the Internet.
Again there are obvious security issues involved with granting the public access to what traditionally has been a limited access resource. We will assume that proper authentication and/or encryption techniques have been used to address these common issues.
A specific problem with the SOAP to CORBA bridge has been addressed above, CORBA object references might themselves convey information which should not be visible to the public. However, using a context as described above effectively masks these and solves the problem.
Having said that, there is a risk of performing "man in the middle" type attacks by "guessing" the issued context key. In our sample implementation this key is a random number with roughly 4 billion possible values so this is a very small risk. Binding the key to external information like originating IP addresses to enable intruder detection and eventual lockout could further reduce this risk. Other, more secure method of establishing the context can also be used.
Apart from malicious persons "guessing" or otherwise obtaining a context key, there is also a "denial of service" attack possible by generating massive numbers of bogus contexts until the context manager runs out of resources. This is a very real danger that might even be caused inadvertently by for instance a Web spider or search engine. Great care should therefore be taken in the implementation of the context manager to detect and avoid this situation.
Finally, "denial of service" attacks are a general problem inherent at publishing information through a Web server in this manner. However, this is once again a general issue that is not specifically caused by deploying a SOAP to CORBA bridge. On the contrary, the very design of CORBA incorporates scalability so it should at least be possible have the back-end services handle any amount of legitimate traffic that is generated.
The author would like to thank all those involved with defining and publishing Open Standards and specifically those who provide implementations of such Standards as Open Source.
The author feels that only by cooperating and sharing in a free and unrestricted manner can computing standards be brought forward to benefit all concerned.
In this respect, the author wishes to extend special thanks to everybody at SourceForge for their excellent service to the Open Source community.
Understanding SOAP Kennard Scribner and Mark C. Stiver Sams Publishing ISBN 0-672-31922-5
Advanced CORBA Programming with C++ Michi Henning and Steve Vinoski Addison-Wesley Longman, Inc. ISBN 0-201-37927-9
The tool used to generate this documentation.
This documentation was generated from the various source files by <img src="doxygen.gif" alt="doxygen" align="middle" border=0 width=110 height=53> by Dimitri van Heesch, © 1997-2000.
Xerces-C from the Apache Group has been used in this project.
See The Apache XML Project homepage for more information.
The CORBA ORB implementation Orbacus 4 has been used in this project.
See the Orbacus homepage for more information.
Walter Stroebel
Lifeline Networks bv
Rivium Westlaan 19
2909 LD Capelle aan den IJssel
Phone: +31 (0) 10 288 1600
Fax: +31 (0) 10 288 1616
Email: soap2corba@lifeline.nl