Ciao a tutti da Enzo,
ho lo stesso problema e non riesco a venirne a capo. potreste postare le righe di codice utili a comporre il security header in C# o VB.net?
Dopo le esperienze con i WS della SOGEI (risolte grazie a Moreno) credevo di essere ormai esperto di web services .... ma mi illudevo. Il problema è che questi della regione puglia hanno dato come riferimento per creare la Security Header solo del codice in Java (che allego in calce) e che non riesco a convertire in .net.
Grazie a chiunque mi fornisca una dritta, anche solo su documentazione da consultare.
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.TimeZone;
import javax.xml.crypto.dsig.CanonicalizationMethod;
import javax.xml.crypto.dsig.DigestMethod;
import javax.xml.crypto.dsig.Reference;
import javax.xml.crypto.dsig.SignatureMethod;
import javax.xml.crypto.dsig.SignedInfo;
import javax.xml.crypto.dsig.Transform;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.spec.C14NmethodParameterSpec;
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
import javax.xml.namespace.Qname;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import com.sun.org.apache.xml.internal.security.utils.Base64;
// *** Dichiarazione di alcune costanti quali namespaces xml
final String NAMESPACEURI_SOAPENV = “http://schemas.xmlsoap.org/soap/envelope/”;
final String prefixUri = “http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-“;
final String NAMESPACEURI_WSSECURITY_WSSE = prefixUri + “wssecurity-secext-1.0.xsd”;
final String NAMESPACEURI_WSSECURITY_WSU = prefixUri + “wssecurity-utility-1.0.xsd”;
final String ATTRIBUTENAME_X509TOKEN = prefixUri + “x509-token-profile-1.0#X509v3”;
final String NAMESPACEURI_WSSECURITY_ENC = prefixUri + “soap-message-security-1.0#Base64Binary”;
// *** Creazione di un messaggio SOAP vuoto e ottenimento dell’oggetto che rappresenta l’header del messaggio SOAP:
//message factory
MessageFactory mf12 = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
//SOAP message
SOAPMessage soapMessage = mf12.createMessage();
// Prepare envelope
SOAPPart soapPart = soapMessage.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
// Prepare header
SOAPHeader header = envelope.getHeader();
if (header == null) {
header = envelope.addHeader();
}
// *** Creazione elemento Security come figlio di Header:
SOAPHeaderElement securityElement = header.addHeaderElement(new Qname(NAMESPACEURI_WSSECURITY_WSSE, “Security”, “wsse”));
securityElement.addNamespaceDeclaration(“wsu”, NAMESPACEURI_WSSECURITY_WSU);
// *** Creazione dell’elemento Timestamp come figlio di Security e creazione elementi data/ora creazione e fine validità messaggio SOAP come figli di Timestamp.
// Generate timestamps
GregorianCalendar creationTime = new GregorianCalendar();
GregorianCalendar expirationTime = new GregorianCalendar();
expirationTime.add(Calendar.MINUTE, 5);
//date formatter
DateFormat dfm = new SimpleDateFormat(“yyyy-MM-dd’T’HH:mm:ss’Z’”);
dfm.setTimeZone(TimeZone.getTimeZone(“GMT”));
// Prepare timestamp element
SOAPElement timeStampElement = securityElement.addChildElement(“Timestamp”, “wsu”);
timeStampElement.addAttribute(new Qname(NAMESPACEURI_WSSECURITY_WSU, “Id”, “wsu”), “timestamp”);
SOAPElement createdElement = timeStampElement.addChildElement(“Created”, “wsu”);
createdElement.addTextNode(dfm.format(creationTime.getTime()));
SOAPElement expiresElement = timeStampElement.addChildElement(“Expires”, “wsu”);
expiresElement.addTextNode(dfm.format(expirationTime.getTime()));
// *** Creazione elemento BinarySecurityToken come figlio di Security. Si rimanda la documentazione del metodo getBase64X509() in seguito.
// Prepare security token element
SOAPElement binarySecurityTokenElement = securityElement.addChildElement(“BinarySecurityToken”, “wsse”);
binarySecurityTokenElement.addAttribute(new Qname(“EncodingType”), NAMESPACEURI_WSSECURITY_ENC);
binarySecurityTokenElement.addAttribute(new Qname(NAMESPACEURI_WSSECURITY_WSU, “Id”, “wsu”), “cert”);
binarySecurityTokenElement.addAttribute(new Qname(“ValueType”), ATTRIBUTENAME_X509TOKEN);
binarySecurityTokenElement.addTextNode(getBase64X509());
// *** Creazione oggetto javax.xml.crypto.dsig.XMLSignatureFactory che facilita la configurazione e la gestione della firma di elementi xml (funzionalità di calcolo digest e firma).
// Signature generation
XMLSignatureFactory signFactory = XMLSignatureFactory.getInstance(“DOM”, new org.jcp.xml.dsig.internal.dom.XMLDSigRI());
// *** Specifica del CanonicalizationMethod
C14NmethodParameterSpec spec1 = null;
javax.xml.crypto.dsig.CanonicalizationMethod c14nMethod = signFactory.newCanonicalizationMethod(CanonicalizationMethod.EXCLUSIVE, spec1);
// *** Specifica del DigestMethod
DigestMethod digestMethod = signFactory.newDigestMethod(DigestMethod.SHA1, null);
// *** Specifica del SignMethod
SignatureMethod signMethod = signFactory.newSignatureMethod(SignatureMethod.RSA_SHA1, null);
// *** Specifica dell’elemento Reference che specifica che la firma si effettua sull’elemento timestamp. Opzionalmente è possibile specificare ulteriori riferimenti.
TransformParameterSpec spec2 = null;
Transform transform = signFactory.newTransform(CanonicalizationMethod.EXCLUSIVE, spec2);
List<Transform> transformList = Collections.singletonList(transform);
List<Reference> referenceList = new ArrayList<Reference>();
Reference reference2 = signFactory.newReference(“#timestamp”, digestMethod, transformList, null, null);
referenceList.add(reference2);
// *** Specifica dell’elemento SignedInfo
SignedInfo signInfo = signFactory.newSignedInfo(c14nMethod, signMethod, referenceList);
// *** Creazione elemento Signature come figlio di Security e generazione del digest e della firma con il certificato contenete chiave pubblica e privata fornito dal metodo getPrivateKey() sulla cui implementazione si rimanda in seguito.
DOMSignContext dsc = new DOMSignContext(getPrivateKey(), securityElement);
XMLSignature signature = signFactory.newXMLSignature(signInfo, null);
signature.sign(dsc);
// *** Creazione elemento KeyInfo come figlio di Signature.
// Prepare key info element
SOAPElement signatureElement = (SOAPElement) securityElement.getLastChild();
SOAPElement keyInfoElement = signatureElement.addChildElement(“KeyInfo”);
// *** Creazione elemento SecurityTokenReference come figlio di KeyInfo
SOAPElement securityTokenReferenceElement = keyInfoElement.addChildElement(“SecurityTokenReference”, “wsse”);
// *** Creazione elemento Reference come figlio di SecurityTokenReference e set dell’attributo URI con il riferimento al certificato pubblico da usare per verificare la firma
SOAPElement referenceElement = securityTokenReferenceElement.addChildElement(“Reference”, “wsse”);
referenceElement.setAttribute(“URI”, “#cert”);
referenceElement.setAttribute(“ValueType”, ATTRIBUTENAME_X509TOKEN);