Use of the security facade from an Axis client

Background

The implementation of the facade for Axis signs request messages to services. The signatures are created in the client by an Axis handler, and a special sub-class of SecurityGuard, AxisClientSecurityGuard is provided to pass credentials into the handlers. Axis requires that the security handler be created when its 'Axis engine' in the client is first created. This means that the handler must set up when constructing the client-side stub for the service.

The grid credentials used to make the signatures are set by accessor methods on the SecurityGuard. Typically, the calling code will get credentials by an exchange with a community service such as MyProxy. (This is a change from earlier versions of this component in which credentials were read from file or obtained directly from a community service by the facade classes themselves.) The following credentials are required for the signature.

  • A certificate chain: one or more X.509 certificates arranged as a chain in which the signature of each certificate is validated using the public key contained in the following certificate. All the certificates must be of type X.509v3. IETF RFC3820 governs their use and arrangement. The trust anchor (i.e. the self-signed, implicitly-trusted certificate that is logically at the end of the chain) is not used in signing a message and should not be included in the chain itself. The chain may be added to the security-guard object either by adding a java.security.cert.certPath to its JAAS subject or by calling the convenience function setCertificateChain which accepts an array of certificates.
  • A private key: a key with which to sign the message. The private key must match the public key in the first certificate in the chain. The key is represented as a java.security.PrivateKey.

The private key is used, by the security-facade classes, actually to sign the message, and it is not sent with the message. The certificate chain is not needed to derive the cryptographic value of the signature, but is sent with the messages in order that the receiving service may verify the signature.

Some aspects of the client-side facade are thus specialized to Axis and the specialization shows in the APIs. Other parts are independent of Axis. If a delegate class is provided to operate the basic messaging mechansim, then this delegate will necessarily be Axis-specific and can encapsulate the Axis-specific calls to the security facade. The other, portable calls to the facade can be left in the code that calls the delagate. Alternatively, the entire client can be specific to Axis. This document describes an Axis-specific delegate in an Axis-independent client.

Configuring Axis handlers

The Axis handler for signing the message must be configured when the AxisEngine for the client is configured. Axis' handler chains are effectively immutable and the security handler cannot easily be injected later.

The handler mechanism is specific to Axis; it is not the standard, JAX-RPC mechanism. Therefore, the handler should be set up in the delegate where Axis-specific code is normal.

If the client stub-classes, called by the delegate, are the kind created by Axis' WSDL2J, then the handlers should be configured when constructing the 'locator' object for the service in question.

import org.astrogrid.security.AxisClientSecurityGuard;
XyzLocator locator = new XyzLocator(AxisClientSecurityGuard.getEngineConfiguration());
  			

Note the use of a static method on AxisClientSecurityGuard to provide the configuration object. This configures the 'java', 'local' and 'http' transports with the signature handler and no other special handlers.

With the locator configured in this way, all proxy objects created from the locator will have the signature handler.

If the client's AxisEngine is being configured from a WSDD document, then the method above does not work. Instead, the WSDD document should declare org.astrogrid.security.AxisClientCredentialHandler as a request handler.

Creating a security-guard object

The portable code of the client (that part that is not specific to Axis) should instantiate the generic SecurityGuard class. This object will be used to gather the credentials.

import org.astrogrid.security.SecurityGuard;
SecurityGuard guard = new SecurityGuard();
  			

One SecurityGuard is needed per user identity but that same object can and should be reused for all delegates created by the client.

Setting credentials

The client application should obtain a certificate chain and matching private key. These may be had, in exchange for a user name and password, from the community services. The security facade does not, currently, interact with the community services on behalf of the application.

import java.security.PrivateKey;
import java.security.cert.X509Certificate;
X509Certificate[] chain = ...;
PrivateKey key = ...;
  			

The client application should store the credentials in the SecurityGuard.

guard.setCertificateChain(chain);
guard.setPrivateKey(key);
  		  

Passing grid credentials to the handler

The Axis-specific code is assumed to be encapsulated in a delegate class. The client application should create the delegate and pass to it the generic security guard.

XyzDelegate delegate = ...
delegate.setCreadentials(guard);
  			

To get the grid credentials into the signature handler, the client must embed them in an instance of AxisClientSecurityGuard. This object should be created from the generic SecurityGuard inside the delegate.

import org.astrogrid.security.AxisClientSecurityGuard;
AxisClientSecurityGuard axisGuard = new AxisClientSecurityGuard(guard);
  			

The Axis-specific guard must then be told to pass its credentials to the handler.

XyzPortType proxy = locator.getXyzPort(endpoint);
axisGuard.configureStub((org.apache.axis.client.Stub)proxy);
  			

In this example, the locator and proxy classes are those created by WSDL2Java. Once the proxy is configured, all outgoing messages are signed, by the handler, with the credentials in the security-guard object.

If the client application uses the Axis stubs directly, without a delegate layer, then the application can create the AxisSecurityGuard directly instead of creating a generic SecurityGuard. The setCertificateChain and setPrivateKey methods can then be used on the Axis guard.

Supporting jars

Your client will need a number of additional jars in order to operate the security handlers.

astrogrid-security.jar
Contains the security facade including the handler org.astrogrid.security.AxisClientCredentialHandler. Also contains the necessary classes from Apache WSS4J.
xmlsec.jar (version 1.2.1 or later)
Contains the code for digital signature on XML.
bcprov.jar ("the bouncy-castle jar"; version jdk13-128 or later)
Contains the cryptographic algorithms used in digital signature.
cog-jglobus.jar (version 1.2)
The Java CoG kit, from which are drawn the classes supporting RFC3820.
cog-puretls.jar (version 1.2)
Supports cog-jglobus.jar.