Example of an AC using the authentication library

From GEANT2-JRA1 Wiki

There is available a Java library for AC developers, so you can add a security token in the request sent to a perfSONAR service. Its main purpose is that ACs are not WS-SEC aware. The class diagram of this library is:

Class diagram for the AC library

The main inteface, AuthNData, provides two methods for adding a X.509 certificate in the request message. At the moment, there is only one class which implements that interface: WSSAuthNData. When we call any of both methods, the message parameter is a SOAPBodyElement and it returns a SOAPEnvelope object:

public SOAPEnvelope addSecurityToken(SOAPBodyElement requestMessage, String privateKeyFile, String certFile) {
            AuthNData authnData=AuthNDataFactory.getDefaultAuthNData();
            Object reqRaw=authnData.addX509STInMessage(requestMessage, keyFile, certFile);
            SOAPEnvelope envelope=(SOAPEnvelope)reqRaw;
            return envelope
}

Full code of SOAPX509Client using this library

package org.perfsonar.client.testHarness;
 
import java.io.File;
import java.io.FileWriter;
import java.net.URL;
 
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
 
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.message.SOAPBodyElement;
import org.apache.axis.message.SOAPEnvelope;
import org.apache.axis.utils.XMLUtils;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.w3c.dom.Document;
 
import org.perfsonar.client.commons.authn.AuthNData;
import org.perfsonar.client.commons.authn.AuthNDataFactory;
 
/**
 *  Class which provides the basic web service (Doc/Lit) client capability
 *  without stubs but including the possibility of sending the X.509
 *  certificate security token.
 *
 *  @author kan
 */
 
public class SOAPX509Client {
 
    @SuppressWarnings(value={"deprecation"})
    public void makeRequest(String[] args) {
        try {
            String endPoint = null;
            String inputFile = null;
            String outputFile = null;
            String keyFile = null;
            String certFile = null;
            if (args.length == 5) {
                endPoint = args[0];
                inputFile = args[1];
                outputFile = args[2];
                keyFile = args[3];
                certFile = args[4];
            } else {
            	System.out.println("Error: Wrong number ("+args.length+") of parameters!!!");
                return;
            }
            System.out.println("End point: " + endPoint);
            System.out.println("Request file: " + inputFile);
            System.out.println("Response file: " + outputFile);
            System.out.println("Private key file: " + keyFile);
            System.out.println("Certificate file: " + certFile);
 
            // prepare to call - set service elements 
            Service service = new Service();
            Call call = (Call)service.createCall();
            call.setTargetEndpointAddress(new URL(endPoint));
            call.setOperationName(new QName("http://soapinterop.org/","submit"));
 
 
            // read the request into a org.w3c.DOM.Document 
 
            Document request = null;
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setNamespaceAware(true);
 
            DocumentBuilder builder = factory.newDocumentBuilder();
            request = builder.parse(new File(inputFile));
 
 
            // build a SOAPBodyElement from the document
 
            SOAPBodyElement requestMessage = 
                new SOAPBodyElement(request.getDocumentElement());
 
            AuthNData authnData=AuthNDataFactory.getDefaultAuthNData();
            Object reqRaw=authnData.addX509STInMessage(requestMessage, keyFile, certFile);
            SOAPEnvelope envelope=(SOAPEnvelope)reqRaw;
 
            // Saving SOAP message
            saveSOAPMessage(envelope.getAsDocument(), inputFile);
 
            // get a timestamp.
            double startTime = 
                new Long(System.currentTimeMillis()).doubleValue();
 
            // call on the end point 
 
            Object resultObject = call.invoke(envelope);
 
            // get another timestamp
            double endTime = 
                new Long(System.currentTimeMillis()).doubleValue();
 
            // result object is a vector - strange!!! But this is how the world works :-D
            // we will now extract the result from the vector
 
            SOAPEnvelope envelopeResult;
            SOAPBodyElement resultSBE;
            Document result = null;
            try {
 
            	envelopeResult= (SOAPEnvelope)resultObject;
                saveSOAPMessage(envelopeResult.getAsDocument(), outputFile);
                resultSBE= envelopeResult.getFirstBody();
 
                // change it to document - here is where validity
                // can be checked..
                result = resultSBE.getAsDocument();
 
                // output it to a file
                File response = new File(outputFile);
                FileWriter outWriter = new FileWriter(response);
 
                OutputFormat format = new OutputFormat( result );
                format.setIndent(4);
                format.setIndenting(true);
                format.setLineSeparator("\n");
 
                XMLSerializer serial = new XMLSerializer(outWriter, format );
                serial.asDOMSerializer();
                serial.serialize( result.getDocumentElement() );
 
                outWriter.close();
            } catch (ClassCastException e) {
                e.printStackTrace();
                System.out.println("SOAPX509Client.makeRequest: We didn't get a Vector of SOAPBodyElements!");
            } catch (Exception e) {
                System.out.println("SOAPX509Client.makeRequest: General exception while retrieving report");
                e.printStackTrace();
            }
            System.out.println("time taken :"+((endTime-startTime)/1000d)+" secs");
        } catch(Exception e) {
            System.err.println("SOAPX509Client.makeRequest: General exception encountered by client");
            e.printStackTrace();
        }
 
        System.out.println("Client exiting");
    }
 
    private void saveSOAPMessage(Document doc, String file) {
        try {
            File response = new File(file+".soap.xml");
            FileWriter outWriter = new FileWriter(response);
            XMLUtils.PrettyElementToWriter(doc.getDocumentElement(),outWriter);
            outWriter.close();
        } catch (Exception e) {
            System.out.println("SOAPX509Client.saveSOAPMessage: General exception while writing SOAP message");
            e.printStackTrace();
        }
    }
 
    public static void main(String[] args) {
        SOAPX509Client doclitClient = new SOAPX509Client();
        doclitClient.makeRequest(args);
 
    }
}
Personal tools