AbstractOpenSPCoop2Message_saaj_impl.java
- /*
- * GovWay - A customizable API Gateway
- * https://govway.org
- *
- * Copyright (c) 2005-2025 Link.it srl (https://link.it).
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 3, as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- package org.openspcoop2.message.soap;
- import java.io.OutputStream;
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Locale;
- import javax.activation.DataHandler;
- import javax.xml.namespace.QName;
- import javax.xml.soap.AttachmentPart;
- import javax.xml.soap.MimeHeaders;
- import javax.xml.soap.SOAPBody;
- import javax.xml.soap.SOAPElement;
- import javax.xml.soap.SOAPEnvelope;
- import javax.xml.soap.SOAPException;
- import javax.xml.soap.SOAPFactory;
- import javax.xml.soap.SOAPFault;
- import javax.xml.soap.SOAPHeader;
- import javax.xml.soap.SOAPHeaderElement;
- import javax.xml.soap.SOAPMessage;
- import javax.xml.soap.SOAPPart;
- import javax.xml.transform.Source;
- import javax.xml.transform.dom.DOMSource;
- import org.apache.commons.io.output.CountingOutputStream;
- import org.apache.wss4j.common.WSS4JConstants;
- import org.openspcoop2.message.ForwardConfig;
- import org.openspcoop2.message.OpenSPCoop2MessageFactory;
- import org.openspcoop2.message.OpenSPCoop2MessageProperties;
- import org.openspcoop2.message.constants.Costanti;
- import org.openspcoop2.message.constants.MessageType;
- import org.openspcoop2.message.exception.MessageException;
- import org.openspcoop2.message.exception.MessageNotSupportedException;
- import org.openspcoop2.message.soap.reader.OpenSPCoop2MessageSoapStreamReader;
- import org.openspcoop2.message.soap.reference.AttachmentReference;
- import org.openspcoop2.message.soap.reference.ElementReference;
- import org.openspcoop2.message.soap.reference.Reference;
- import org.openspcoop2.message.xml.MessageDynamicNamespaceContextFactory;
- import org.openspcoop2.message.xml.MessageXMLUtils;
- import org.openspcoop2.message.xml.XPathExpressionEngine;
- import org.openspcoop2.utils.LoggerWrapperFactory;
- import org.openspcoop2.utils.dch.DataContentHandlerManager;
- import org.openspcoop2.utils.transport.http.ContentTypeUtilities;
- import org.openspcoop2.utils.transport.http.HttpConstants;
- import org.openspcoop2.utils.xml.AbstractXPathExpressionEngine;
- import org.openspcoop2.utils.xml.DynamicNamespaceContext;
- import org.openspcoop2.utils.xml.XPathNotFoundException;
- import org.openspcoop2.utils.xml.XPathReturnType;
- import org.w3c.dom.Element;
- import org.w3c.dom.Node;
- import org.w3c.dom.NodeList;
- /**
- * AbstractXMLBaseOpenSPCoop2Message
- *
- * @author Andrea Poli (apoli@link.it)
- * @author $Author$
- * @version $Rev$, $Date$
- */
- public abstract class AbstractOpenSPCoop2Message_saaj_impl extends AbstractBaseOpenSPCoop2SoapMessage {
- private SOAPMessage soapMessage;
- protected SOAPMessage _getSoapMessage() {
- return this.soapMessage;
- }
- public AbstractOpenSPCoop2Message_saaj_impl(OpenSPCoop2MessageFactory messageFactory, SOAPMessage soapMessage){
- super(messageFactory);
- this.soapMessage = soapMessage;
- }
-
-
- /* Informazioni SOAP (senza costruire il DOM) */
-
- @Override
- public OpenSPCoop2MessageSoapStreamReader getSoapReader() throws MessageException,MessageNotSupportedException {
- //throw new MessageException("NotImplemented; use soap impl");
- return null;
- }
-
-
-
- /* Metodi SOAP */
-
- @Override
- protected SOAPMessage _getSOAPMessage() throws MessageException{
- return this.soapMessage;
- }
-
- @Override
- public SOAPPart getSOAPPart() throws MessageException,MessageNotSupportedException{
- return this.soapMessage.getSOAPPart();
- }
-
- @Override
- public SOAPBody getSOAPBody() throws MessageException,MessageNotSupportedException{
- try{
- return this.soapMessage.getSOAPBody();
- }catch(Exception e){
- throw new MessageException(e.getMessage(),e);
- }
- }
-
- @Override
- public boolean hasSOAPFault() throws MessageException,MessageNotSupportedException{
- SOAPBody body = getSOAPBody();
- return body!=null && body.hasFault();
- }
-
- @Override
- public boolean isSOAPBodyEmpty() throws MessageException,MessageNotSupportedException{
- SOAPBody body = getSOAPBody();
- boolean hasContent = body!=null;
- if(hasContent){
- hasContent = SoapUtils.getFirstNotEmptyChildNode(this.messageFactory, body, false)!=null;
- }
- return !hasContent;
- }
-
- @Override
- public SOAPHeader getSOAPHeader() throws MessageException,MessageNotSupportedException{
- try{
- return this.soapMessage.getSOAPHeader();
- }catch(Exception e){
- throw new MessageException(e.getMessage(),e);
- }
- }
-
-
-
- /* Attachments SOAP */
-
- @Override
- public void addAttachmentPart(AttachmentPart attachmentPart) throws MessageException,MessageNotSupportedException{
- this.soapMessage.addAttachmentPart(attachmentPart);
- }
-
- @Override
- public AttachmentPart createAttachmentPart(DataHandler dataHandler) throws MessageException,MessageNotSupportedException{
- return this.soapMessage.createAttachmentPart(dataHandler);
- }
-
- @Override
- public AttachmentPart createAttachmentPart() throws MessageException,MessageNotSupportedException{
- return this.soapMessage.createAttachmentPart();
- }
-
- @Override
- public boolean hasAttachments() throws MessageException,MessageNotSupportedException{
- return this.soapMessage.countAttachments()>0;
- }
-
- @Override
- public int countAttachments() throws MessageException,MessageNotSupportedException{
- return this.soapMessage.countAttachments();
- }
-
- @Override
- public Iterator<?> getAttachments() throws MessageException,MessageNotSupportedException{
- return this.soapMessage.getAttachments();
- }
-
- @Override
- public Iterator<?> getAttachments(MimeHeaders headers) throws MessageException,MessageNotSupportedException{
- String[] values = headers.getHeader("Content-Id");
- if(values.length > 0 && (!values[0].startsWith("<") || !values[0].endsWith(">"))) {
- headers.removeHeader("Content-Id");
- headers.setHeader("Content-Id", "<" + values[0] + ">");
- }
- return this.soapMessage.getAttachments(headers);
- }
-
- @Override
- public AttachmentPart getAttachment(SOAPElement element) throws MessageException,MessageNotSupportedException{
- try{
- return this.soapMessage.getAttachment(element);
- }catch(Exception e){
- throw new MessageException(e.getMessage(),e);
- }
- }
-
- @Override
- public void removeAllAttachments() throws MessageException,MessageNotSupportedException{
- this.soapMessage.removeAllAttachments();
- }
-
- @Override
- public void removeAttachments(MimeHeaders mhs) throws MessageException,MessageNotSupportedException{
- this.soapMessage.removeAttachments(mhs);
- // Aggiorno il Content-Type se sono finiti gli Attachments.
- if(this.soapMessage.countAttachments() == 0){
- this.setContentType(HttpConstants.CONTENT_TYPE_SOAP_1_1);
- }
- }
-
- @Override
- public void updateAttachmentPart(AttachmentPart ap,DataHandler dh) throws MessageException,MessageNotSupportedException{
- ap.setDataHandler(dh);
- }
-
- @Override
- public void updateAttachmentPart(AttachmentPart ap,byte[]content,String contentType) throws MessageException,MessageNotSupportedException {
- // Se si usa il solo metodo del ramo else, in tomcat si ottiene il seguente errore (con dump abilitato):
- // ... Unable to run the JAXP transformer on a stream [B cannot be cast to javax.xml.transform.Source (sourceException: Error during saving a multipart message)
- try {
- String baseType = ContentTypeUtilities.readBaseTypeFromContentType(contentType);
- if(HttpConstants.CONTENT_TYPE_TEXT_XML.equals(baseType)) {
- Source streamSource = null;
- DataContentHandlerManager dchManager = new DataContentHandlerManager(LoggerWrapperFactory.getLogger(AbstractOpenSPCoop2Message_saaj_impl.class));
- if(dchManager.readMimeTypesContentHandler().containsKey(HttpConstants.CONTENT_TYPE_TEXT_XML)) {
- // Se è non registrato un content handler per text/xml
- // succede se dentro l'ear non c'e' il jar mailapi e l'application server non ha caricato il modulo mailapi (es. tramite versione standalone standard)
- // e si usa il metodo seguente DOMSource si ottiene il seguente errore:
- // javax.xml.soap.SOAPException: no object DCH for MIME type text/xml
- // at com.sun.xml.messaging.saaj.soap.MessageImpl.writeTo(MessageImpl.java:1396) ~[saaj-impl-1.3.28.jar:?]
- //System.out.println("XML (DOMSource)");
- streamSource = new DOMSource(MessageXMLUtils.getInstance(this.messageFactory).newElement(content));
- }
- else {
- // Se è registrato un content handler per text/xml
- // e succede se dentro l'ear c'e' il jar mailapi oppure se l'application server ha caricato il modulo mailapi (es. tramite versione standalone full)
- // e si usa il metodo seguente StreamSource, si ottiene il seguente errore:
- // Unable to run the JAXP transformer on a stream org.xml.sax.SAXParseException; Premature end of file. (sourceException: Error during saving a multipart message)
- // com.sun.xml.messaging.saaj.SOAPExceptionImpl: Error during saving a multipart message
- // at com.sun.xml.messaging.saaj.soap.MessageImpl.writeTo(MessageImpl.java:1396) ~[saaj-impl-1.3.28.jar:?]
- // at org.openspcoop2.message.Message1_1_FIX_Impl.writeTo(Message1_1_FIX_Impl.java:172) ~[openspcoop2_message_BUILD-13516.jar:?]
- // at org.openspcoop2.message.OpenSPCoop2Message_11_impl.writeTo
- //System.out.println("XML (StreamSource)");
- streamSource = new javax.xml.transform.stream.StreamSource(new java.io.ByteArrayInputStream(content));
- }
- ap.setContent(streamSource, contentType);
- }
- else {
- this.updateAttachmentPart(ap, new DataHandler(content,contentType));
- }
- }catch(Exception e) {
- throw new MessageException(e.getMessage(),e);
- }
- }
-
- @Override
- public void updateAttachmentPart(AttachmentPart ap,String content,String contentType) throws MessageException,MessageNotSupportedException {
- this.updateAttachmentPart(ap, new DataHandler(content,contentType));
- }
-
-
- /* ContentID Attachments SOAP */
-
- @Override
- public String createContentID(String ns) throws MessageException,MessageNotSupportedException{
- return _createContentID(ns);
- }
- protected static String _createContentID(String ns) throws MessageException,MessageNotSupportedException{
- try{
- return "<" + org.apache.cxf.attachment.AttachmentUtil.createContentID(ns) + ">";
- }catch(Exception e){
- throw new MessageException(e.getMessage(),e);
- }
- }
-
-
-
-
-
- /* Trasporto */
-
- @Override
- public OpenSPCoop2MessageProperties getForwardTransportHeader(ForwardConfig forwardConfig) throws MessageException{
- OpenSPCoop2MessageProperties msg = super.getForwardTransportHeader(forwardConfig);
- return new OpenSPCoop2MessageMimeHeaderProperties(this.soapMessage,msg);
- }
-
- /* ContentType */
-
- protected abstract String _super_getContentType();
-
- @Override
- public void updateContentType() throws MessageException {
- try{
- if(countAttachments() > 0){
- if(saveRequired()) {
- saveChanges();
- }
- }
- else {
-
- if(saveRequired()) {
-
- boolean pulizia = false;
- String contentType = _super_getContentType();
- if((ContentTypeUtilities.isMtom(contentType)) ){
- // Bug Fix: OP-375 'Unable to internalize message' con messaggi senza attachments con ContentType 'multipart/related; ...type="application/xop+xml"'
- // Capita per i messaggi che contengono un content type multipart e però non sono effettivamente presenti attachments.
- saveChanges();
- pulizia = true;
- }
- else if((ContentTypeUtilities.isMultipartRelated(contentType)) ){
- // Bug Fix: OP-678 'Unable to internalize message' con messaggi senza attachments con ContentType 'multipart/related; ...type="text/xml"'
- // Capita per i messaggi che contengono un content type multipart e però non sono effettivamente presenti attachments.
- saveChanges();
- pulizia = true;
- }
-
- if(pulizia) {
- try {
- javax.mail.internet.ContentType ctObj = new javax.mail.internet.ContentType(contentType);
-
- // Bug Fix: OP-909
- // Rimane il tipo 'Multipart-Type' come Content-Type in caso di messaggio 'MTOM' senza allegati.
- String contentTypeInternal = ContentTypeUtilities.getInternalMultipartContentType(contentType);
- javax.mail.internet.ContentType ctObjInternal = new javax.mail.internet.ContentType(contentTypeInternal);
- ctObj.setPrimaryType(ctObjInternal.getPrimaryType());
- ctObj.setSubType(ctObjInternal.getSubType());
-
- String type = ctObj.getParameter(HttpConstants.CONTENT_TYPE_MULTIPART_PARAMETER_TYPE);
- if(type!=null && !type.equals("")) {
- ctObj.getParameterList().remove(HttpConstants.CONTENT_TYPE_MULTIPART_PARAMETER_TYPE);
- }
-
- String boundary = ctObj.getParameter(HttpConstants.CONTENT_TYPE_MULTIPART_PARAMETER_BOUNDARY);
- if(boundary!=null && !boundary.equals("")) {
- ctObj.getParameterList().remove(HttpConstants.CONTENT_TYPE_MULTIPART_PARAMETER_BOUNDARY);
- }
-
- String start = ctObj.getParameter(HttpConstants.CONTENT_TYPE_MULTIPART_PARAMETER_START);
- if(start!=null && !start.equals("")) {
- ctObj.getParameterList().remove(HttpConstants.CONTENT_TYPE_MULTIPART_PARAMETER_START);
- }
-
- String startInfo = ctObj.getParameter(HttpConstants.CONTENT_TYPE_MULTIPART_PARAMETER_START_INFO);
- if(startInfo!=null && !startInfo.equals("")) {
- ctObj.getParameterList().remove(HttpConstants.CONTENT_TYPE_MULTIPART_PARAMETER_START_INFO);
- }
-
- this.setContentType(ctObj.toString());
-
- }catch(Throwable t) {
- System.err.println("Pulizia messaggio Multipart normalizzato senza attachment non riuscita: "+t.getMessage());
- t.printStackTrace(System.err);
- }
- }
- }
-
- }
- }catch(Exception e){
- throw new MessageException(e.getMessage(),e);
- }
- }
-
- /* WriteTo e Save */
-
- @Override
- public boolean isContentBuilded() {
- return true; // e' insito nel costruttore
- }
-
- @Override
- public void writeTo(OutputStream os, boolean consume) throws MessageException{
- try{
- CountingOutputStream cos = new CountingOutputStream(os);
- this.soapMessage.writeTo(cos);
- this.outgoingsize = cos.getByteCount();
- }catch(Exception e){
- throw new MessageException(e.getMessage(),e);
- }
- }
-
- @Override
- public void saveChanges() throws MessageException{
- try{
- this.soapMessage.saveChanges();
- }catch(Exception e){
- throw new MessageException(e.getMessage(),e);
- }
- }
-
- @Override
- public boolean saveRequired(){
- return this.soapMessage.saveRequired();
- }
-
-
-
- /* SOAP Utilities */
-
- @Override
- public Element getFirstChildElement(SOAPElement element) throws MessageException,MessageNotSupportedException {
- return _getFirstChildElement(element);
- }
- protected static Element _getFirstChildElement(SOAPElement element) throws MessageException,MessageNotSupportedException {
- Element firstElement = null;
- NodeList nl = element.getChildNodes();
- if(nl!=null) {
- for (int i = 0; i < nl.getLength(); i++) {
- Node tmp = nl.item(i);
- if(tmp instanceof Element) {
- firstElement = (Element) tmp;
- break;
- }
- }
- }
- /**
- * Usato anzi 'element.getChildNodes()'; il metodo getChildElements, in un soap body faceva perdere tutti gli altri elementi nella validazione dei contenuti usando il dynamic namespace context
- * Iterator<?> it = element.getChildElements();
- while (it.hasNext() && firstElement==null){
- Node tmp = (Node) it.next();
- if(tmp instanceof Element) firstElement = (Element) tmp;
- }*/
- return firstElement;
- }
-
- @Override
- public SOAPElement createSOAPElement(byte[] bytes) throws MessageException,MessageNotSupportedException {
- return _createSOAPElement(bytes, this.getMessageType(), this.messageFactory);
- }
- protected static SOAPElement _createSOAPElement(byte[] bytes, MessageType messageType, OpenSPCoop2MessageFactory messageFactory) throws MessageException,MessageNotSupportedException {
- try{
- SOAPFactory soapFactory = null;
- if(MessageType.SOAP_11.equals(messageType)){
- soapFactory = messageFactory.getSoapFactory11();
- }
- else if(MessageType.SOAP_12.equals(messageType)){
- soapFactory = messageFactory.getSoapFactory12();
- }
- else{
- throw new MessageException("MessageType ["+messageType+"] not supported");
- }
- return soapFactory.createElement(MessageXMLUtils.getInstance(messageFactory).newElement(bytes));
- }catch(Exception e){
- throw new MessageException(e.getMessage(),e);
- }
- }
-
- @Override
- public SOAPHeaderElement newSOAPHeaderElement(SOAPHeader hdr,QName name) throws MessageException,MessageNotSupportedException {
- return _newSOAPHeaderElement(hdr,name);
- }
- protected static SOAPHeaderElement _newSOAPHeaderElement(SOAPHeader hdr,QName name) throws MessageException,MessageNotSupportedException {
- try{
- SOAPHeaderElement newHeader = hdr.addHeaderElement(name);
- return newHeader;
- }catch(Exception e){
- throw new MessageException(e.getMessage(),e);
- }
- }
-
- @Override
- public void addHeaderElement(SOAPHeader hdr,SOAPHeaderElement hdrElement) throws MessageException,MessageNotSupportedException{
- _addHeaderElement(hdr, hdrElement);
- }
- protected static void _addHeaderElement(SOAPHeader hdr,SOAPHeaderElement hdrElement) throws MessageException,MessageNotSupportedException{
- try{
- hdr.addChildElement(hdrElement);
- }catch(Exception e){
- throw new MessageException(e.getMessage(),e);
- }
- }
-
- @Override
- public void removeHeaderElement(SOAPHeader hdr,SOAPHeaderElement hdrElement) throws MessageException,MessageNotSupportedException{
- _removeHeaderElement(hdr, hdrElement);
- }
- protected static void _removeHeaderElement(SOAPHeader hdr,SOAPHeaderElement hdrElement) throws MessageException,MessageNotSupportedException{
- try{
- hdr.removeChild(hdrElement);
- }catch(Exception e){
- throw new MessageException(e.getMessage(),e);
- }
- }
-
- @Override
- public void setFaultCode(SOAPFault fault, SOAPFaultCode code,
- QName eccezioneName) throws MessageException,MessageNotSupportedException {
- _setFaultCode(fault, code, eccezioneName);
- }
- protected static void _setFaultCode(SOAPFault fault, SOAPFaultCode code,
- QName eccezioneName) throws MessageException,MessageNotSupportedException {
- try{
- fault.setFaultCode(eccezioneName);
- }catch(Exception e){
- throw new MessageException(e.getMessage(),e);
- }
- }
-
- @Override
- public void setFaultString(SOAPFault fault, String message) throws MessageException,MessageNotSupportedException{
- _setFaultString(fault, message);
- }
- protected static void _setFaultString(SOAPFault fault, String message) throws MessageException,MessageNotSupportedException{
- try{
- SoapUtils.setFaultString(fault, message, null);
- }catch(Exception e){
- throw new MessageException(e.getMessage(),e);
- }
- }
- @Override
- public void setFaultString(SOAPFault fault, String message, Locale locale) throws MessageException,MessageNotSupportedException{
- _setFaultString(fault, message, locale);
- }
- protected static void _setFaultString(SOAPFault fault, String message, Locale locale) throws MessageException,MessageNotSupportedException{
- try{
- SoapUtils.setFaultString(fault, message, locale);
- }catch(Exception e){
- throw new MessageException(e.getMessage(),e);
- }
- }
-
-
-
- /* Ws Security */
-
- private SOAPPart getSOAPPartForSearchWSSecurity(){
- return this.soapMessage.getSOAPPart();
- }
-
- @Override
- public List<Reference> getWSSDirtyElements(String actor, boolean mustUnderstand) throws MessageException,MessageNotSupportedException {
-
- try{
-
- List<Reference> references = new ArrayList<Reference>();
-
- // Prendo il security Header di mia competenza
- SOAPElement security = (SOAPElement) WSSecurityUtils.getSecurityHeader(this.getSOAPPartForSearchWSSecurity(),this.messageType, actor,
- this.isThrowExceptionIfFoundMoreSecurityHeader());
-
- //TODO verificare se actor==null && mustUnderstand==false?
- if(security!=null){
- // Prendo i riferimenti agli elementi cifrati
- Iterator<?> it = security.getChildElements(new QName(WSS4JConstants.ENC_NS, WSS4JConstants.ENC_KEY_LN));
- if(it.hasNext()){
- SOAPElement encryptedKey = (SOAPElement) it.next();
- SOAPElement referenceList = (SOAPElement) encryptedKey.getChildElements(new QName(WSS4JConstants.ENC_NS, WSS4JConstants.REF_LIST_LN)).next();
- List<SOAPElement> referenceListElements = SoapUtils.getNotEmptyChildSOAPElement(referenceList);
- for (int i = 0; i < referenceListElements.size(); i++) {
- String referenceWithSharp = referenceListElements.get(i).getAttributeValue(new QName("URI"));
- // Il riferimento presenta un # prima dell'identificativo se e' un elemento o cid: se e' un attachment
- if(referenceWithSharp.startsWith("#")){
- String reference = referenceWithSharp.substring(1);
- // Vado a vedere se ' cifrato {Content} o {Element}
- SOAPElement encryptedElement = (SOAPElement) org.apache.wss4j.common.util.XMLUtils.findElementById(this.getSOAPPartForSearchWSSecurity().getEnvelope(), reference, true);
- if(encryptedElement==null){
- throw new SOAPException("Element with 'Id' attribute value ("+referenceWithSharp+") not found "+Costanti.FIND_ERROR_ENCRYPTED_REFERENCES);
- }
-
- // Verifico se sto cifrando un attachment
- QName qName = new QName(WSS4JConstants.ENC_NS, "CipherData");
- Iterator<?> childElements = encryptedElement.getChildElements(qName);
- if(childElements!=null && childElements.hasNext()){
-
- QName qNameReference = new QName(WSS4JConstants.ENC_NS, "CipherReference");
- Iterator<?> childElementsReference = ((SOAPElement)childElements.next()).getChildElements(qNameReference);
- if(childElementsReference!=null && childElementsReference.hasNext()){
-
- // Attachment cifrato
- String referenceAttach = ((SOAPElement) childElementsReference.next()).getAttributeValue(new QName("URI"));
- if(referenceAttach.startsWith("cid:")){
- String referenceCID = referenceAttach.substring(4);
- references.add(new AttachmentReference (AttachmentReference.TYPE_ENCRYPT_ATTACHMENT, referenceCID));
- }else{
- throw new SOAPException("Element 'CipherReference' with attribute 'cid' wrong "+Costanti.FIND_ERROR_ENCRYPTED_REFERENCES);
- }
-
- }else{
-
- // Elemento cifrato
- if(encryptedElement.getAttributeNS(null, "Type").equals(WSS4JConstants.ENC_NS + "Content"))
- references.add(new ElementReference(encryptedElement.getParentElement(), ElementReference.TYPE_ENCRYPT_CONTENT, reference));
- else
- references.add(new ElementReference (encryptedElement.getParentElement(), ElementReference.TYPE_ENCRYPT_ELEMENT, reference));
- }
- }
- else{
- throw new SOAPException("Element 'CipherData' not found "+Costanti.FIND_ERROR_ENCRYPTED_REFERENCES);
- }
-
- }
- }
- }
-
- // Prendo i riferimenti agli elementi firmati
- it = security.getChildElements(new QName(WSS4JConstants.SIG_NS, WSS4JConstants.SIG_LN));
- if(it.hasNext()){
- SOAPElement signature = (SOAPElement) it.next();
- SOAPElement signatureInfo = (SOAPElement) signature.getChildElements(new QName(WSS4JConstants.SIG_NS, "SignedInfo")).next();
- Iterator<?> referenceIterator = signatureInfo.getChildElements(new QName(WSS4JConstants.SIG_NS, "Reference"));
- while (referenceIterator.hasNext()) {
- String referenceWithSharp = ((SOAPElement) referenceIterator.next()).getAttributeValue(new QName("URI"));
- // Il riferimento presenta un # prima dell'identificativo se e' un elemento o cid: se e' un attachment
- if(referenceWithSharp.startsWith("#")){
- String reference = referenceWithSharp.substring(1);
-
- SOAPEnvelope soapEnvelope = this.getSOAPPartForSearchWSSecurity().getEnvelope();
-
- SOAPElement signedElement = (SOAPElement) org.apache.wss4j.common.util.XMLUtils.findElementById(soapEnvelope, reference, true);
- if(signedElement==null){
-
- // Provo a vedere se l'elemento firmato e' una Assertion
-
- DynamicNamespaceContext dnc = null;
- if(MessageType.SOAP_11.equals(this.getMessageType())) {
- dnc = MessageDynamicNamespaceContextFactory.getInstance(this.messageFactory).getNamespaceContextFromSoapEnvelope11(soapEnvelope);
- } else {
- dnc = MessageDynamicNamespaceContextFactory.getInstance(this.messageFactory).getNamespaceContextFromSoapEnvelope12(soapEnvelope);
- }
-
- AbstractXPathExpressionEngine xpathExpressionEngine = new XPathExpressionEngine(this.messageFactory);
-
- try {
- String xpath = Costanti.XPATH_SAML_20_ASSERTION + "[@"+Costanti.SAML_20_ASSERTION_ID+"='"+reference+"']";
- Object o = xpathExpressionEngine.getMatchPattern(security, dnc, xpath, XPathReturnType.NODE);
- signedElement = (SOAPElement) o;
- } catch(XPathNotFoundException e) {}
-
- if(signedElement==null){
- try {
- String xpath = Costanti.XPATH_SAML_11_ASSERTION + "[@"+Costanti.SAML_11_ASSERTION_ID+"='"+reference+"']";
- Object o = xpathExpressionEngine.getMatchPattern(security, dnc, xpath, XPathReturnType.NODE);
- signedElement = (SOAPElement) o;
- } catch(XPathNotFoundException e) {}
- }
-
- if(signedElement==null){
- throw new SOAPException("Element with 'Id' attribute value ("+referenceWithSharp+") not found "+Costanti.FIND_ERROR_SIGNATURE_REFERENCES);
- }
- }
- references.add(new ElementReference (signedElement, ElementReference.TYPE_SIGNATURE, reference));
- } else if(referenceWithSharp.startsWith("cid:")){
- String reference = referenceWithSharp.substring(4);
- references.add(new AttachmentReference(AttachmentReference.TYPE_SIGN_ATTACHMENT, reference));
- }
- }
- }
- }
-
- return references;
-
- }catch(Exception e){
- throw new MessageException(e.getMessage(),e);
- }
- }
-
- @Override
- public void cleanWSSDirtyElements(String actor, boolean mustUnderstand, List<Reference> references, boolean detachHeaderWSSecurity, boolean removeAllIdRef) throws MessageException,MessageNotSupportedException {
-
- try{
-
- // Prendo il security Header di mia competenza
- SOAPElement security = (SOAPElement) WSSecurityUtils.getSecurityHeader(this.getSOAPPartForSearchWSSecurity(),this.messageType, actor,
- this.isThrowExceptionIfFoundMoreSecurityHeader());
-
- // Rimuovo l'header Security
- if(detachHeaderWSSecurity){
- security.detachNode();
- }
-
- boolean found;
-
- // Pulisco i nodi sporchi
- for(int i=0; i<references.size(); i++){
- Reference reference = references.get(i);
- if(reference instanceof ElementReference) {
- SOAPElement elementToClean = ((ElementReference)reference).getElement();
- switch (reference.getType()) {
- case ElementReference.TYPE_SIGNATURE:
- // Devo vedere se altri hanno firmato l'elemento ed in tal caso lasciar fare l'id ed il namespace
- found = false;
- NodeList securities = this.getSOAPHeader().getElementsByTagNameNS(WSS4JConstants.WSSE_NS, WSS4JConstants.WSSE_LN);
- for(int s=0; s<securities.getLength(); s++){
- security = (SOAPElement) securities.item(s);
- // Prendo i riferimenti agli elementi firmati
- Iterator<?> it = security.getChildElements(new QName(WSS4JConstants.SIG_NS, WSS4JConstants.SIG_LN));
- if(it.hasNext()){
- SOAPElement signature = (SOAPElement) it.next();
- SOAPElement signatureInfo = (SOAPElement) signature.getChildElements(new QName(WSS4JConstants.SIG_NS, "SignedInfo")).next();
- Iterator<?> referenceIterator = signatureInfo.getChildElements(new QName(WSS4JConstants.SIG_NS, "Reference"));
- while (referenceIterator.hasNext()) {
- String referenceWithSharp = ((SOAPElement) referenceIterator.next()).getAttributeValue(new QName("URI"));
- if(reference.getReference().equals(referenceWithSharp.substring(1))) {
- found = true;
- }
- }
- }
- }
- if(!found) {
-
- boolean removeIdRefSignature = false;
- if(removeAllIdRef){
- // alcune implementazioni vecchie generano degli attributi wsu:Id 'zombie' che quindi non possono essere ripuliti controllandoli con le reference.
- // Per poter interoperare con tali implementazioni è possibile abilitare tale opzione
- removeIdRefSignature = true;
- elementToClean.removeAttributeNS(WSS4JConstants.WSU_NS, "Id");
- }
- else{
- String valoreRefSignature = elementToClean.getAttributeNS(WSS4JConstants.WSU_NS, "Id");
- // fix: l'id puo' appartenere ad un altro header wssecurity con diverso actor/mustUnderstand. Controllo il valore.
- //System.out.println("CHECK TYPE_SIGNATURE ["+valoreRefSignature+"] ["+reference.getReference()+"]");
- if(valoreRefSignature!=null && valoreRefSignature.equals(reference.getReference())){
- removeIdRefSignature = true;
- }
-
- if(removeIdRefSignature){
- elementToClean.removeAttributeNS(WSS4JConstants.WSU_NS, "Id");
- }
- }
-
- List<String> prefixesToRemoveContent = new ArrayList<>();
- Iterator<?> prefixes = elementToClean.getNamespacePrefixes();
- while(prefixes.hasNext()){
- String prefix = (String) prefixes.next();
- String namespace = elementToClean.getNamespaceURI(prefix);
- if(namespace.equals(WSS4JConstants.WSU_NS)) {
- if(removeIdRefSignature){
- prefixesToRemoveContent.add(prefix);
- }
- }
- }
- for(int y=0; y<prefixesToRemoveContent.size(); y++)
- elementToClean.removeNamespaceDeclaration(prefixesToRemoveContent.get(y));
- }
- break;
-
- case ElementReference.TYPE_ENCRYPT_CONTENT:
- List<String> prefixesToRemoveContent = new ArrayList<>();
- Iterator<?> prefixesContent = elementToClean.getNamespacePrefixes();
- while(prefixesContent.hasNext()){
- String prefix = (String) prefixesContent.next();
- String namespace = elementToClean.getNamespaceURI(prefix);
- if(namespace.equals(WSS4JConstants.ENC_NS) || namespace.equals(elementToClean.getNamespaceURI(prefix))){
- prefixesToRemoveContent.add(prefix);
- }
- }
- for(int y=0; y<prefixesToRemoveContent.size(); y++)
- elementToClean.removeNamespaceDeclaration(prefixesToRemoveContent.get(y));
-
- boolean removeIdRefEncContent = false;
- if(removeAllIdRef){
- // alcune implementazioni vecchie generano degli attributi wsu:Id 'zombie' che quindi non possono essere ripuliti controllandoli con le reference.
- // Per poter interoperare con tali implementazioni è possibile abilitare tale opzione
- removeIdRefEncContent = true;
- elementToClean.removeAttributeNS(WSS4JConstants.WSU_NS, "Id");
- }
- else{
- String valoreRefEncContent = elementToClean.getAttributeNS(WSS4JConstants.WSU_NS, "Id");
- // fix: l'id puo' appartenere ad un altro header wssecurity con diverso actor/mustUnderstand. Controllo il valore.
- //System.out.println("CHECK TYPE_ENCRYPT_CONTENT ["+valoreRefEncContent+"] ["+reference.getReference()+"]");
- if(valoreRefEncContent!=null && valoreRefEncContent.equals(reference.getReference())){
- removeIdRefEncContent = true;
- }
-
- if(removeIdRefEncContent){
- elementToClean.removeAttributeNS(WSS4JConstants.WSU_NS, "Id");
- }
- }
-
- prefixesToRemoveContent = new ArrayList<>();
- prefixesContent = elementToClean.getNamespacePrefixes();
- while(prefixesContent.hasNext()){
- String prefix = (String) prefixesContent.next();
- String namespace = elementToClean.getNamespaceURI(prefix);
- if(namespace.equals(WSS4JConstants.WSU_NS)) {
- if(removeIdRefEncContent){
- prefixesToRemoveContent.add(prefix);
- }
- }
- }
- for(int y=0; y<prefixesToRemoveContent.size(); y++)
- elementToClean.removeNamespaceDeclaration(prefixesToRemoveContent.get(y));
- break;
-
- case ElementReference.TYPE_ENCRYPT_ELEMENT:
- // Questo codice si occupa di pulire la "sporcizia" wss presente comunque nel elemento cifrato e decifrato.
- // Poiche' non c'e' modo, esaminando il messaggio cifrato, di identificare (nome e namespace da decifrare) l'elemento cifrato per intero, si e' scelto di tenersi traccia del padre,
- // e a questo punto di ripulire tutti i figli che contengono sporcizia.
- // Eventuali figli cifrati in modalita' 'content' rientreranno comunque anche in questa casistica.
- Iterator<?> childrenToClean = elementToClean.getChildElements();
- while(childrenToClean.hasNext()) {
- Object next = childrenToClean.next();
- if(next instanceof SOAPElement) {
- SOAPElement childToClean = (SOAPElement) next;
- List<String> prefixesToRemoveElement = new ArrayList<>();
- Iterator<?> prefixesElement = childToClean.getNamespacePrefixes();
- while(prefixesElement.hasNext()){
- String prefix = (String) prefixesElement.next();
- String namespace = childToClean.getNamespaceURI(prefix);
- if(namespace.equals(WSS4JConstants.WSU_NS)){
- prefixesToRemoveElement.add(prefix);
- }
- }
- for(int y=0; y<prefixesToRemoveElement.size(); y++)
- childToClean.removeNamespaceDeclaration(prefixesToRemoveElement.get(y));
-
- boolean removeIdRefEncElement = false;
- if(removeAllIdRef){
- // alcune implementazioni vecchie generano degli attributi wsu:Id 'zombie' che quindi non possono essere ripuliti controllandoli con le reference.
- // Per poter interoperare con tali implementazioni è possibile abilitare tale opzione
- removeIdRefEncContent = true;
- childToClean.removeAttributeNS(WSS4JConstants.WSU_NS, "Id");
- }
- else{
- String valoreRefEncElement = childToClean.getAttributeNS(WSS4JConstants.WSU_NS, "Id");
- // fix: l'id puo' appartenere ad un altro header wssecurity con diverso actor/mustUnderstand. Controllo il valore.
- //System.out.println("CHECK TYPE_ENCRYPT_ELEMENT ["+valoreRefEncElement+"] ["+reference.getReference()+"]");
- if(valoreRefEncElement!=null && valoreRefEncElement.equals(reference.getReference())){
- removeIdRefEncElement = true;
- }
-
- if(removeIdRefEncElement){
- childToClean.removeAttributeNS(WSS4JConstants.WSU_NS, "Id");
- }
- }
-
- prefixesToRemoveElement = new ArrayList<>();
- prefixesElement = childToClean.getNamespacePrefixes();
- while(prefixesElement.hasNext()){
- String prefix = (String) prefixesElement.next();
- String namespace = childToClean.getNamespaceURI(prefix);
- if(namespace.equals(WSS4JConstants.WSU_NS)) {
- if(removeIdRefEncElement){
- prefixesToRemoveElement.add(prefix);
- }
- }
- }
- for(int y=0; y<prefixesToRemoveElement.size(); y++)
- childToClean.removeNamespaceDeclaration(prefixesToRemoveElement.get(y));
- }
- }
- break;
-
- default:
- break;
- }
- }
- }
-
- }catch(Exception e){
- throw new MessageException(e.getMessage(),e);
- }
- }
-
- /* Ws Security (SoapBox) */
-
- @Override
- public String getEncryptedDataHeaderBlockClass() {
- return _getEncryptedDataHeaderBlockClass();
- }
- protected static String _getEncryptedDataHeaderBlockClass() {
- return "com.sun.xml.wss.core.EncryptedDataHeaderBlock"; // usare la stringa per GPL clean
- }
- @Override
- public String getProcessPartialEncryptedMessageClass() {
- return _getProcessPartialEncryptedMessageClass();
- }
- protected static String _getProcessPartialEncryptedMessageClass() {
- return "org.openspcoop2.security.message.soapbox.ProcessPartialEncryptedMessage";
- }
- @Override
- public String getSignPartialMessageProcessorClass() {
- return _getSignPartialMessageProcessorClass();
- }
- protected static String _getSignPartialMessageProcessorClass() {
- return "org.openspcoop2.security.message.soapbox.SignPartialMessageProcessor";
- }
-
-
- }