All Downloads are FREE. Search and download functionalities are using the official Maven repository.

no.digipost.api.interceptors.EbmsClientInterceptor Maven / Gradle / Ivy

The newest version!
package no.digipost.api.interceptors;

import no.digipost.api.exceptions.MessageSenderValidationException;
import no.digipost.api.representations.EbmsAktoer;
import no.digipost.api.representations.EbmsContext;
import no.digipost.api.representations.Organisasjonsnummer;
import no.digipost.api.security.OrgnummerExtractor;
import no.digipost.api.xml.Constants;
import no.digipost.api.xml.JaxbMarshaller;
import no.digipost.api.xml.Marshalling;
import no.digipost.org.oasis_open.docs.ebxml_msg.ebms.v3_0.ns.core._200704.Error;
import no.digipost.org.oasis_open.docs.ebxml_msg.ebms.v3_0.ns.core._200704.Messaging;
import no.digipost.org.oasis_open.docs.ebxml_msg.ebms.v3_0.ns.core._200704.SignalMessage;
import no.digipost.org.oasis_open.docs.ebxml_msg.ebms.v3_0.ns.core._200704.UserMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ws.client.WebServiceClientException;
import org.springframework.ws.client.support.interceptor.ClientInterceptor;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.soap.SoapHeader;
import org.springframework.ws.soap.SoapHeaderElement;
import org.springframework.ws.soap.SoapMessage;
import org.w3c.dom.Element;

import javax.xml.transform.dom.DOMSource;

import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import static java.lang.String.format;
import static no.digipost.api.xml.Constants.MESSAGING_QNAME;

public class EbmsClientInterceptor implements ClientInterceptor {

    private final JaxbMarshaller marshaller;
    private final EbmsAktoer tekniskMottaker;
    private final OrgnummerExtractor extractor = new OrgnummerExtractor();

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    public EbmsClientInterceptor(JaxbMarshaller marshaller, EbmsAktoer tekniskMottaker) {
        this.marshaller = marshaller;
        this.tekniskMottaker = tekniskMottaker;
    }

    @Override
    public boolean handleRequest(MessageContext messageContext) throws WebServiceClientException {
        SoapMessage requestMessage = (SoapMessage) messageContext.getRequest();
        Element bodyElement = (Element) ((DOMSource) requestMessage.getSoapBody().getSource()).getNode();
        bodyElement.setAttributeNS(Constants.WSSEC_UTILS_NAMESPACE, "wsu:Id", "soapBody");
        bodyElement.setIdAttributeNS(Constants.WSSEC_UTILS_NAMESPACE, "Id", true);

        SoapHeader soapHeader = requestMessage.getSoapHeader();
        EbmsContext context = EbmsContext.from(messageContext);
        SoapHeaderElement ebmsHeader = soapHeader.addHeaderElement(MESSAGING_QNAME);
        ebmsHeader.setMustUnderstand(true);
        context.processRequest(context, ebmsHeader, requestMessage);
        return true;
    }

    @Override
    public boolean handleResponse(MessageContext messageContext) throws WebServiceClientException {
        SoapMessage saajSoapMessage = (SoapMessage) messageContext.getResponse();
        Iterator soapHeaderElementIterator = saajSoapMessage.getSoapHeader().examineHeaderElements(MESSAGING_QNAME);
        if (!soapHeaderElementIterator.hasNext()) {
            throw new MessageSenderValidationException("Missing required ebMS SOAP header");
        }
        SoapHeaderElement ebmsMessaging = soapHeaderElementIterator.next();
        Messaging messaging = Marshalling.unmarshal(marshaller, ebmsMessaging, Messaging.class);
        EbmsContext context = EbmsContext.from(messageContext);
        List warnings = new ArrayList();
        for (SignalMessage message : messaging.getSignalMessages()) {
            for (Error error : message.getErrors()) {
                // Error i ebms-header uten SOAP-fault er warning. Severity failure gir SOAP-fault.
                warnings.add(error);
            }
            if (message.getReceipt() != null) {
                context.receipts.add(message);
            }
        }
        if (warnings.size() > 0) {
            if (warnings.size() > 1) {
                // If this happens in practice, we should log what the warnings are.
                log.warn("Got more than one ebMS warning in response. Using the first, discarding the rest.");
            }

            context.warning = warnings.get(0);
        }


        for (UserMessage userMessage : messaging.getUserMessages()) {
            context.userMessage = userMessage;
        }
        context.processResponse(context, ebmsMessaging, saajSoapMessage);
        if (messageContext.containsProperty(Wss4jInterceptor.INCOMING_CERTIFICATE)) {
            X509Certificate cert = (X509Certificate) messageContext.getProperty(Wss4jInterceptor.INCOMING_CERTIFICATE);
            Organisasjonsnummer responder = extractor.from(cert);
            if (!tekniskMottaker.orgnr.equals(responder)) {
                throw new MessageSenderValidationException(format("Unexpected signer in incoming message. Expected: [%s] Extracted: [%s] from %s", tekniskMottaker.orgnr, responder, cert.getSubjectX500Principal().getName()));
            }
        }
        return true;
    }

    @Override
    public boolean handleFault(final MessageContext messageContext) throws WebServiceClientException {
        return true;
    }

    @Override
    public void afterCompletion(final MessageContext messageContext, final Exception ex) throws WebServiceClientException {

    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy