6.1.2.1.
Setting up Message Handlers
Up one level
Overview
The SOAP messages that are generated by the OGSA-DAI client-side library require slight modifications to become compatible with the GRIA OGSA-DAI client. These modifications include:
- Removing the Data Resource ID from the URL so that all calls go to a single remote service.
- Adding the Data Resource ID as a SOAP header inside the message.
- Signing the request with the user's certificate, and verifying the signature of the response from the service.
- Including user authentication information to ensure that other users cannot access any OGSA-DAI sessions you create.
- Adding tokens to assert group membership.
These modifications are performed by an AXIS message handler chain - a collection of Java classes that can change the SOAP message at various stages during its processing. More information about message handlers is available in the Axis documentation.
Bundling JAR files
In order to use the GRIA OGSA-DAI service in an existing OGSA-DAI client application, you must bundle the following additional JAR files with your application:
From the GRIA client distribution:
- commons-httpclient-3.0.1.jar
- commons-codec-1.3.jar
- gria-account-common-2.jar
- gria-infra-common-2.jar
- gria-sla-common-2.jar
- wss4j-1.5.0-itinnov-1.jar
- xalan-2.7.0.jar
- xmlsec-1.3.0-itinnov-1.jar
From the GRIA OGSA-DAI Client distribution:
- gria-ogsadai-clienthandlers-5.2.jar
- gria-ogsadai-client-5.2.jar
Configuring the Implementation Factory
GRIA uses an ImplementationFactory class to locate implementations for a given interface. You should add the following line to an implementationfactory.properties in your classpath:
uk.ac.soton.itinnovation.grid.utils.Transport = uk.ac.soton.ecs.iam.grid.comms.client.AxisTransport
Setting the Keystore
The message handlers need to use a certificate to sign all outgoing SOAP messages. Information about which certificate to use is held in a crypto.properties file loaded from the classpath. Your application should prompt the user for a keystore and generate this file automatically.
A sample crypto.properties file is shown below:
org.apache.ws.security.crypto.merlin.file=/home/bob/my-keystore.ks
org.apache.ws.security.crypto.merlin.keystore.password=password
org.apache.ws.security.crypto.merlin.keystore.alias=Bob
org.apache.ws.security.crypto.merlin.alias.password=password
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=JKS
The GRIA Client generates a crypto.properties file the first time it is run, saving it in the conf directory relative to the gridcli executable. If you have used the GRIA Client before you can use this file to test your OGSA-DAI application.
Note that your application will need to tell Java to use your keystore before making any calls to OGSA-DAI. This can be done by using the OgsaDaiSSLHelper class once on application startup:
OgsaDaiSSLHelper.setupKeystore();
Configuring the WSSD
Axis loads a client-config.wsdd file from the classpath to retrieve information about the message handler chains you wish to use in your application.
A suitable client-config.wsdd file is shown below. If you already have such a file in your application you will need to adapt it to include the sections shown in this example.
<?xml version='1.0'?>
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:grid-acct="http://www.it-innovation.soton.ac.uk/uk/ac/soton/itinnovation/grid/service/types"
xmlns:grid="http://www.it-innovation.soton.ac.uk/2004/grid"
xmlns:service-types="http://www.it-innovation.soton.ac.uk/uk/ac/soton/itinnovation/grid/service/types"
xmlns:grid-types="http://www.it-innovation.soton.ac.uk/uk/ac/soton/itinnovation/grid/types"
xmlns:wsa="http://www.w3.org/2005/08/addressing"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<globalConfiguration>
<parameter name="attachment_encapsulation_format" value="axis.attachment.style.dime"/>
<parameter name="disablePrettyXML" value="true"/>
<parameter name="enableNamespacePrefixOptimization" value="false" />
<parameter name="enableSignatureConfirmation" value="false"/> <!-- Needed for .NET compat -->
<requestFlow>
<handler type="java:uk.ac.soton.itinnovation.grid.client.ogsadai.OgsaDaiRequestHandler" />
<handler type="java:uk.ac.soton.itinnovation.grid.utils.wss4j.handler.WSOutboundHandler" >
<handler type="java:uk.ac.soton.itinnovation.grid.client.ogsadai.OgsaDaiSAMLHandler" >
<parameter name="action" value="Timestamp Signature"/>
<parameter name="signaturePropFile" value="crypto.properties" />
<parameter name="signatureKeyIdentifier" value="DirectReference" />
<parameter name="signatureParts" value="{}{http://schemas.xmlsoap.org/soap/envelope/}Body;{}{http://it-innovation.soton.ac.uk/2005/grid}ConversationID;{}{http://it-innovation.soton.ac.uk/2005/grid}BillingInformation;{}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;{}{http://it-innovation.soton.ac.uk/2005/grid}OwnerRule"/>
<parameter name="passwordCallbackClass"
value="uk.ac.soton.itinnovation.grid.utils.PWCallback"/>
</handler>
</requestFlow>
<responseFlow>
<handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
<parameter name="action" value="Signature"/>
<parameter name="signaturePropFile" value="crypto.properties" />
</handler>
</responseFlow>
</globalConfiguration>
<handler name="LocalResponder" type="java:org.apache.axis.transport.local.LocalResponder"/>
<handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper"/>
<typeMapping qname="grid-types:X509Certificate"
languageSpecificType="java:java.security.cert.X509Certificate"
serializer="uk.ac.soton.itinnovation.grid.types.CertificateSerializerFactory"
deserializer="uk.ac.soton.itinnovation.grid.types.CertificateDeserializerFactory"
encodingStyle=""/>
<typeMapping qname="wsa:EndpointReferenceType"
languageSpecificType="java:org.apache.axis.message.addressing.EndpointReferenceType"
serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
encodingStyle=""/>
<typeMapping qname="wsa:ReferenceParametersType"
languageSpecificType="java:org.apache.axis.message.addressing.ReferenceParametersType"
serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
encodingStyle=""/>
<typeMapping qname="xsd:anyURI"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
languageSpecificType="java:java.net.URL"
serializer="org.apache.axis.encoding.ser.SimpleSerializerFactory"
deserializer="org.apache.axis.encoding.ser.SimpleDeserializerFactory"
encodingStyle=""/>
<typeMapping qname="service-types:SLATemplate"
languageSpecificType="java:uk.ac.soton.itinnovation.grid.service.types.SLATemplate"
serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
encodingStyle=""/>
<typeMapping qname="service-types:SLAProposal"
languageSpecificType="java:uk.ac.soton.itinnovation.grid.service.types.SLAProposal"
serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
encodingStyle=""/>
<typeMapping qname="service-types:Constraint"
languageSpecificType="java:uk.ac.soton.itinnovation.grid.service.types.Constraint"
serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
encodingStyle=""/>
<typeMapping qname="service-types:Bound"
languageSpecificType="java:uk.ac.soton.itinnovation.grid.service.types.Bound"
serializer="org.apache.axis.encoding.ser.EnumSerializerFactory"
deserializer="org.apache.axis.encoding.ser.EnumDeserializerFactory"
encodingStyle=""/>
<typeMapping qname="service-types:TimePeriod"
languageSpecificType="java:uk.ac.soton.itinnovation.grid.service.types.TimePeriod"
serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
encodingStyle=""/>
<typeMapping qname="service-types:PermittedService"
languageSpecificType="java:uk.ac.soton.itinnovation.grid.service.types.PermittedService"
serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
encodingStyle=""/>
<typeMapping qname="service-types:Metric"
languageSpecificType="java:uk.ac.soton.itinnovation.grid.service.types.Metric"
serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
encodingStyle=""/>
<typeMapping qname="service-types:PricingTerm"
languageSpecificType="java:uk.ac.soton.itinnovation.grid.service.types.PricingTerm"
serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
encodingStyle=""/>
<typeMapping qname="grid-acct:StatementEvent"
languageSpecificType="java:uk.ac.soton.itinnovation.grid.service.types.StatementEvent"
serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
encodingStyle=""/>
<typeMapping qname="grid-acct:AccountStatement"
languageSpecificType="java:uk.ac.soton.itinnovation.grid.service.types.AccountStatement"
serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
encodingStyle=""/>
<typeMapping qname="grid-types:SubjectDescription"
languageSpecificType="java:uk.ac.soton.itinnovation.grid.types.SubjectDescription"
serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
encodingStyle=""/>
<typeMapping qname="grid:IDType"
languageSpecificType="java:uk.ac.soton.itinnovation.grid.types.IDType"
serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
encodingStyle=""/>
<typeMapping qname="grid-acct:account-statementType"
languageSpecificType="java:uk.ac.soton.itinnovation.grid.service.types.AccountStatement"
serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
encodingStyle=""/>
<typeMapping qname="grid-types:MatchRule"
languageSpecificType="java:uk.ac.soton.itinnovation.grid.types.MatchRule"
serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
encodingStyle=""/>
<typeMapping qname="service-types:UsageReport"
languageSpecificType="java:uk.ac.soton.itinnovation.grid.service.types.UsageReport"
serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
encodingStyle=""/>
<typeMapping qname="service-types:Metric"
languageSpecificType="java:uk.ac.soton.itinnovation.grid.service.types.Metric"
serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
encodingStyle=""/>
<!-- This prevents "Could not convert org.apache.axis.types.URI" errors when sending EndpointReferenceTypes as arguments -->
<typeMapping qname="wsa:AttributedURI"
languageSpecificType="java:org.apache.axis.message.addressing.AttributedURI"
serializer="org.apache.axis.encoding.ser.SimpleSerializerFactory"
deserializer="org.apache.axis.encoding.ser.SimpleDeserializerFactory"
encodingStyle=""/>
<transport name="http" pivot="java:org.apache.axis.transport.http.CommonsHTTPSender"/>
<transport name="local">
<responseFlow>
<handler type="LocalResponder"/>
</responseFlow>
</transport>
</deployment>
