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:
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 }
[edit]
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); } }

