简体   繁体   中英

Obtain a SOAP message and sign in java

I have a WebService developed in NetBeans and look like this:

import _504.iec62325.wss._1._0.MsgFaultMsg;
import ch.iec.tc57._2011.schema.message.ErrorType;
import ch.iec.tc57._2011.schema.message.FaultMessageType;
import ch.iec.tc57._2011.schema.message.HeaderType;
import ch.iec.tc57._2011.schema.message.ReplyType;
import ch.iec.tc57._2011.schema.message.ResponseMessageType;
import javax.jws.WebService;
import javax.xml.ws.BindingType;
import ch.iec.tc57._2011.schema.message.RequestMessageType;
...

@WebService(serviceName = "ServiceEME", portName = "Service_EME_Port", 
        endpointInterface = "_504.iec62325.wss._1._0.PortTFEDIType", 
        targetNamespace = "urn:iec62325.504:wss:1:0", 
        wsdlLocation = "WEB-INF/wsdl/ServiceEME/servicioCS.wsdl")
@BindingType(value = "http://java.sun.com/xml/ns/jaxws/2003/05/soap/bindings/HTTP/")

public class ServiceEME 
{
    @Resource

    private static final String CONTEXT = "PRODUCTION";
    private final String DATA_TYPE = "datatype";
    private final String SERVER_TIMESTAMP = "servertimestamp";
    private final String VERB_GET = "get";
    private final String NOUN_QUERYDATA = "querydata";
    private static final String NOUN_LIST = "messagelist"; 
    private static final String NOUN_ANY = "any"; 

    private static enum TipoMensaje {
        QUERY_DATA,
        MESSAGE_LIST,
        MESSAGE_GET;
    }

    public ResponseMessageType request (RequestMessageType parameter) 
                                        throws MsgFaultMsg 
    { 
        Document msgAsDocument = null;
        RSAPrivateKey privateKey = null;
        X509Certificate cert = null;
        try 
        {
            switch(getMessageType(parameter)) 
            {
                case QUERY_DATA :  
                    return QueryData.procesar(parameter);
                case MESSAGE_LIST :
                    return MessagesList.procesar(parameter);
                case MESSAGE_GET :
                    return GetMessage.procesar(parameter);
                default:
                    throw componerError("Error", "Error");
            }
        }
        catch ( InterpretaInputException ex ) 
        {
            throw componerError(ex.getCode(), ex.getMessage() );
        }
    }
...

public static void signDocument(final Document msgAsDocument, final
    RSAPrivateKey privateKey, final X509Certificate cert) 
                                                throws InterpretaInputException
    {
        try 
        {
            XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
            List<Transform> trfLst = new ArrayList<>();
            trfLst.add(fac.newTransform(Transform.ENVELOPED,
                                                (TransformParameterSpec) null));
            trfLst.add(fac.newCanonicalizationMethod(CanonicalizationMethod.
                                    INCLUSIVE, (C14NMethodParameterSpec) null));
            Reference ref = fac.newReference("", fac.newDigestMethod
                                    (DigestMethod.SHA1,null), trfLst, null, null);
            SignedInfo si = fac.newSignedInfo(fac.newCanonicalizationMethod
                (CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null),
                fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
                Collections.singletonList(ref));
            Node headerNode = null;
            NodeList nl = msgAsDocument.getElementsByTagNameNS
                            ("http://iec.ch/TC57/2011/schema/message", "Header");

            if (nl.getLength() == 1) 
            {
                headerNode = nl.item(0);
            } 
            else 
            {//Header error
                throw new InterpretaInputException(
                   Constants.ERROR_QRY_004_CODE, Constants.ERROR_QRY_004_DETAIL);
            }

            DOMSignContext dsc = new DOMSignContext(privateKey, headerNode);
            KeyInfoFactory keyInfoFactory = fac.getKeyInfoFactory();
            List<Object> x509Content = new ArrayList<>();

            x509Content.add(keyInfoFactory.newX509IssuerSerial(cert.
                                getIssuerDN().getName(), cert.getSerialNumber()));
            x509Content.add(cert.getSubjectX500Principal().getName());
            x509Content.add(cert);
            X509Data xd = keyInfoFactory.newX509Data(x509Content);

            KeyInfo keyInfo = keyInfoFactory.newKeyInfo
                                                (Collections.singletonList(xd));
            XMLSignature signature = fac.newXMLSignature(si, keyInfo);

            signature.sign(dsc);
        }
        catch (Exception e) 
        { //Simplified exception handling for brevity
            throw new InterpretaInputException(
                   Constants.ERROR_HAND_009_CODE, Constants.ERROR_HAND_009_DETAIL);
        }
    }
}

The Service response without problem but now I need to add a signature based on a server certificate. This signature is generated through the signDocument function as you can see in the code.

My problem is that I have a custom response "ResponseMessageType" and I dont know how to convert this response to a Document type in order to generate the signature tag and add it to the message. This three items

Document msgAsDocument = null;
RSAPrivateKey privateKey = null;
X509Certificate cert = null;

Are emtpy because I dont know how to convert my ResponseMessageType to msgAsDocument.

I have been reading different sites and maybe I need to use a handler to intercept the SOAP message but I can figure out how to intercept my own answer and introduce it on the message before send it.

Thank you in advance.

I solved the problem adding a Handler.

public class SignHandler implements SOAPHandler<SOAPMessageContext>
....
@Override
public boolean handleMessage(SOAPMessageContext context) 
{
    //System.out.println("Server : handleMessage()......");
    Boolean isResponse = (Boolean) context.get(MessageContext.
                                                MESSAGE_OUTBOUND_PROPERTY);
    if(isResponse)
    {
        try
        {
            SOAPMessage soapMsg = context.getMessage();
            Source source = soapMsg.getSOAPPart().getContent();   
            Node root = null;
...

Too many new concepts for me today.

Thanks!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM