An example using the techniques discussed in this article is available in Article 70106
Traditional, non-secure connections are made with the HTTP protocol, using a URL such as "http://www.webobjects.com." A web browser will attempt an HTTP connection with the server on port 80 unless another port is specified. By changing the "http://" to "https://", e.g. "https://www.webobjects.com", the web browser will attempt to connect to the server via SSL. This connection defaults to port 443.
Setting up a secure server is beyond the scope of this article. For assistance, contact one of the Certificate Authorities such as VeriSign (at www.verisign.com), RSA (at www.rsa.com), Entrust (at www.entrust.com), or Thawte (at www.thawte.com).
Why Doesn't WebObjects Support SSL?
Actually, it does! An entire WebObjects application can be run in SSL mode by starting it with an "https:" URL. However, encrypting and decrypting every page uses system resources. Also, there's no way to switch between HTTP and SSL. This is because WebObjects generates URL's relative to the server root, omitting the protocol prefix. For example, a typical URL generated by WebObjects starts with "/cgi-bin/WebObjects/..." instead of a complete URL like "http://www.webobjects.com/cgi-bin/WebObjects/...".
Why does WebObjects generate these abbreviated URL's? Once the initial URL is given with the protocol, host name, and (optional) port number, these don't need to be re-specified for every connection. The same protocol, host name, and port numbers are used for subsequent connections. Omitting them saves on system overhead, and in most cases they're not needed anyway.
Adding SSL Support to WebObjects
To switch to SSL mode, your app must generating a URL beginning with "https://". To switch back, it must generate a URL beginning with "http://". Both of these tasks require that WebObjects generate complete URL's, instead of URL's relative to the server's document root (/cgi-bin/WebObjects/...). There is a private method in WOContext which allows this, called _generateCompleteURLs. Calling this method during the request-response loop ensures that all subsequently-generated URL's in the response have URL's beginning with "http://", followed by the host name and (optional) port number.
The _generateCompleteURLs method prefixes URL's with the value of the WOCGIAdaptorURL variable. This value can be set from the command line when launching the application (with the -WOCGIAdaptorURL flag), through user defaults, programatically via WOApplication methods, or via Monitor. WOCGIAdaptorURL defaults to "http://localhost/cgi-bin/WebObjects". Despite its name, WOCGIAdaptorURL is also used by the NSAPI and IIS adaptors. The user default WOAdaptorURL may also be used for compatibility, although this is not recognized as a command-line option.
Now that we can generate complete URL's, and specify the prefix, all that's required to generate a URL pointing to a secure server is to get the value of WOCGIAdaptorURL, change the "http" prefix to "https", and call _generateCompleteURLs. For example:
url = [[WOApplication cgiAdaptorURL] mutableCopy];
range = [url rangeOfString:@"http://"];
if (range.length > 0) {
[url replaceCharactersInRange:range withString:@"https://"];
[WOApplication setCGIAdaptorURL:url];
}
[context _generateCompleteURLs];
This code is from the enableSSLInContext method of the SSL class, available for download as part of the WebObjects 4 SSL Example, Article 70106. Executing this code anytime during the request-response loop will cause all subsequently-generated URL's to link to the secure server; the disableSSLInContext method switches back to "http://". These methods are written in Objective C, but are "wrapped" for use in Java.
Mixing Normal and Secure URL's
A major limitation of the above code is that it changes the protocol for an entire page. To mix normal and secure URL's on a page, you must know exactly where in the request-response loop to change the protocol, and where to change it back.
A new dynamic element, SSLContainer, has been provided in the SSL Example. This element can be "wrapped" around any block of HTML, and any URL's generated by WebObjects inside the SSLContainer will have an "https://" prefix. The element does not take any bindings. For example, consider the following HTML:
<webobject name=GiftIdeas>
</webobject>
<webobject name=ContinueShopping>
</webobject>
<webobject name=SecureArea>
<webobject name=Checkout>
</webobject>
</webobject>
And the following wod:
GiftIdeas: CatalogPage { ... }
ContinueShopping: WOActiveImage { ... }
SecureArea: SSLContainer { }
Checkout: WOActiveImage { ... }
All of the URL's on the page will start with"http://", except for the link to the checkout page, which will start with "https://". Since it works similarly to the WOComponentContent dynamic element, SSLContainer can include any number of nested components.
Known Problems