web-services - seguridad - donde veo mis conversaciones de whatsapp guardadas en gmail
IRS Soap Fault: encabezado de seguridad de WS no válido (2)
Estoy intentando enviar una solicitud de jabón al IRS y enfrentar el mismo error que otros en este grupo: ''Encabezado de seguridad de WS no válido''. ¿alguien me puede guiar con una muestra de solicitud de jabón? Una pregunta más es: como parte del proceso de inscripción, enviamos nuestro certificado X509 (clave pública) al sitio web del IRS, que se usará para autenticar / descifrar los resúmenes de sus mensajes. ¿Qué archivo de certificado cargaste para este proceso? Estamos realmente atascados con este error por días. Apreciar cualquier ayuda sobre esto. He visto 2 preguntas sobre este tema, pero no hay respuestas de ayuda.
Estoy asumiendo que esto es para envíos de ACA Air IRS. Cargamos el archivo .cer en el sitio del IRS, donde asocia su TCC (en el formato BBBBB, por ejemplo) con el .cer que cargó. La pila que utilizamos fue: Oracle JDK 8, WSS4J v2.1.4 y CXF v3.1.4. Aquí está el código Java de muestra que usamos para firmar los elementos de referencia que el IRS quiere firmar:
public static SOAPMessage signSoapMessage(SOAPMessage message,
String keystorePassword, String irsPrivateKeyPassword, Class<?> clazz) throws WSSecurityException {
//TODO remove below hard coded
final String _irsPrivateKeyPassword = "yourprivatekeypasswordyougotfromCA";
final String _keystorePassword = "yourpasswordtoyourJKS";
keystorePassword = _keystorePassword;
irsPrivateKeyPassword = _irsPrivateKeyPassword;
PrivateKeyEntry privateKeyEntry = getPrivateKeyEntry(keystorePassword,
irsPrivateKeyPassword);
PrivateKey signingKey = privateKeyEntry.getPrivateKey();
X509Certificate signingCert = (X509Certificate) privateKeyEntry
.getCertificate();
//TODO add alias to database
final String alias = "thealiasforthiscertandprivatekey";
final int signatureValidityTime = 3600; // 1hour in seconds
WSSConfig config = WSSConfig.getNewInstance();
//config.setWsiBSPCompliant(true);
WsuIdAllocator idAllocator = new WsuIdAllocator() {
@Override
public String createSecureId(String prefix, Object o) {
//e.g. <ds:KeyInfo Id="KI-9F6A3A6B473244859D59710683FABFE1">
if(prefix.equals("KI-"))
return "KI-" + UUID.randomUUID().toString().replace("-", "").toUpperCase();
//e.g. <wsse:SecurityTokenReference wsu:Id="STR-E6C0BA1EC73A4AB3BECFEBF6075EF175">
else if (prefix.equals("STR-"))
return "STR-" + UUID.randomUUID().toString().replace("-", "").toUpperCase();
//TODO why is there a condition where prefix.equals("X509") and o.toString() is the public cert?
else
return null;
}
//e.g. <ds:Signature Id="SIG-9850525DA06CE28ED91448475206411147"
@Override
public String createId(String prefix, Object o) {
return "SIG-" + UUID.randomUUID().toString().replace("-", "").toUpperCase();
}
};
config.setIdAllocator(idAllocator );
//WSSecSignature wsSecSignature = new WSSecSignature(config);
WSSecSignature wsSecSignature = new WSSecSignature();
wsSecSignature.setX509Certificate(signingCert);
wsSecSignature.setUserInfo(alias, new String(keystorePassword.toCharArray()));
wsSecSignature.setUseSingleCertificate(true);
wsSecSignature.setKeyIdentifierType(WSConstants.X509_KEY_IDENTIFIER);
//wsSecSignature.setKeyIdentifierType(WSConstants.SKI_KEY_IDENTIFIER);
wsSecSignature.setDigestAlgo(WSConstants.SHA1);
wsSecSignature.setSignatureAlgorithm(WSConstants.RSA_SHA1);
wsSecSignature.setSigCanonicalization(WSConstants.C14N_EXCL_WITH_COMMENTS);
try {
Document document = toDocument(message);
WSSecHeader secHeader = new WSSecHeader(document);
//secHeader.setMustUnderstand(true);
secHeader.insertSecurityHeader();
WSSecTimestamp timestamp = new WSSecTimestamp();
timestamp.setTimeToLive(signatureValidityTime);
document = timestamp.build(document, secHeader);
List<WSEncryptionPart> wsEncryptionParts = new ArrayList<WSEncryptionPart>();
//Very important, ordering of the parts is critical: refer to page 34 of the guide
//for ACAGetTransmitterBulkRequestService, it is Timestamp, ACATransmitterManifestReqDtl, ACABusinessHeader
if(clazz.equals(ACATransmitterManifestReqDtl.class)){
WSEncryptionPart timestampPart = new WSEncryptionPart("Timestamp",
WSConstants.WSU_NS, "");
//This is very important, Timestamp needs to be fist
wsEncryptionParts.add(timestampPart);
WSEncryptionPart aCATransmitterManifestReqDtlPart = new WSEncryptionPart(
"ACATransmitterManifestReqDtl",
"urn:us:gov:treasury:irs:ext:aca:air:7.0", "");
wsEncryptionParts.add(aCATransmitterManifestReqDtlPart);
WSEncryptionPart aCABusinessHeaderPart = new WSEncryptionPart(
"ACABusinessHeader",
"urn:us:gov:treasury:irs:msg:acabusinessheader", "");
wsEncryptionParts.add(aCABusinessHeaderPart);
}
//for ACAGetTransmitterBulkRequestStatus, it is Timestamp, ACABusinessHeader, ACABulkRequestTransmitterStatusDetailRequest
else if(clazz.equals(ACABulkRequestTransmitterStatusDetailRequest.class)){
WSEncryptionPart timestampPart = new WSEncryptionPart("Timestamp",
WSConstants.WSU_NS, "");
//This is very important, Timestamp needs to be fist
wsEncryptionParts.add(timestampPart);
WSEncryptionPart aCABusinessHeaderPart = new WSEncryptionPart(
"ACABusinessHeader",
"urn:us:gov:treasury:irs:msg:acabusinessheader", "");
wsEncryptionParts.add(aCABusinessHeaderPart);
WSEncryptionPart aCABulkRequestTransmitterStatusDetailRequestPart = new WSEncryptionPart(
"ACABulkRequestTransmitterStatusDetailRequest",
"urn:us:gov:treasury:irs:msg:irstransmitterstatusrequest", "");
wsEncryptionParts.add(aCABulkRequestTransmitterStatusDetailRequestPart);
}
wsSecSignature.getParts().addAll(wsEncryptionParts);
Properties properties = new Properties();
properties.setProperty("org.apache.ws.security.crypto.provider",
"org.apache.ws.security.components.crypto.Merlin");
Crypto crypto = CryptoFactory.getInstance(properties);
KeyStore keystore = KeyStore.getInstance("JKS");
java.io.FileInputStream fis = null;
try {
fis = new java.io.FileInputStream(System.getProperty("java.home") + "//lib//security//meckeystore.jks");
if(fis != null) {
keystore.load(fis, keystorePassword.toCharArray());
} else {
//TODO: replace with custom MEC exception
throw new Exception("Unable to read keystore file.");
}
} finally {
if (fis != null) {
fis.close();
}
}
keystore.setKeyEntry(alias, signingKey, keystorePassword.toCharArray(),
new Certificate[]{signingCert});
((Merlin) crypto).setKeyStore(keystore);
crypto.loadCertificate(new ByteArrayInputStream(signingCert.getEncoded()));
document = wsSecSignature.build(document, crypto, secHeader);
updateSOAPMessage(document, message);
} catch (Exception e) {
// throw new
// WSSecurityException(WSSecurityException.Reason.SIGNING_ISSUE, e);
e.printStackTrace();
}
return message;
}
/**
* Changes the SOAPMessage to a dom.Document.
*/
private static Document toDocument(SOAPMessage soapMsg) throws TransformerException,
SOAPException, IOException {
Source src = soapMsg.getSOAPPart().getContent();
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
DOMResult result = new DOMResult();
transformer.transform(src, result);
return (Document) result.getNode();
}
//https://svn.apache.org/repos/asf/webservices/wss4j/branches/WSS4J_1_1_0_FINAL/test/wssec/SOAPUtil.java
private static SOAPMessage updateSOAPMessage(Document doc,
SOAPMessage message)
throws Exception {
DOMSource domSource = new DOMSource(doc);
message.getSOAPPart().setContent(domSource);
return message;
}
Aquí está la muestra de solicitud SOAP
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:us:gov:treasury:irs:ext:aca:air:7.0" xmlns:urn1="urn:us:gov:treasury:irs:common">
<SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<wsse:Security SOAP-ENV:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<ds:Signature Id="SIG-d62ad452-5219-4baf-9708-3ae1d2cf7e92" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#WithComments"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#TS-6450a75d-45e4-463b-a1e8-2d3ae3b4c57c">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<InclusiveNamespaces PrefixList="wsse SOAP-ENV soap urn urn1" xmlns="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>ojqiqHiXxPWIaEumCOO3bKJZ73A=</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#id-0EB7188D138D494EA44AC09FE03F6BEE">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<InclusiveNamespaces PrefixList="SOAP-ENV soap urn urn1" xmlns="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>cm3KGHFWHyJcBU9MEQzw6Ru04z0=</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#id-1183235E8ED44DE99B069411CD4837DC">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<InclusiveNamespaces PrefixList="SOAP-ENV soap urn urn1" xmlns="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>6nM3ONVPyHtiupcznWiixpNG82k=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>removed==</ds:SignatureValue>
<ds:KeyInfo Id="KI-e6a6c681-ccf7-49ab-a37f-dac69c52d32a">
<wsse:SecurityTokenReference wsu:Id="STR-c1b4d47e-fda6-49b0-a58a-7df24ab43e13">
<wsse:KeyIdentifier EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3">removed</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
<wsu:Timestamp wsu:Id="TS-6450a75d-45e4-463b-a1e8-2d3ae3b4c57c">
<wsu:Created>2016-01-27T23:59:36.352Z</wsu:Created>
<wsu:Expires>2016-01-28T00:59:36.352Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
<ACATransmitterManifestReqDtl ns3:Id="id-0EB7188D138D494EA44AC09FE03F6BEE" xmlns="urn:us:gov:treasury:irs:ext:aca:air:7.0" xmlns:ns2="urn:us:gov:treasury:irs:common" xmlns:ns3="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<PaymentYr>2015</PaymentYr>
<PriorYearDataInd>0</PriorYearDataInd>
<ns2:EIN></ns2:EIN>
<TransmissionTypeCd>O</TransmissionTypeCd>
<TestFileCd>T</TestFileCd>
<TransmitterNameGrp>
<BusinessNameLine1Txt></BusinessNameLine1Txt>
<BusinessNameLine2Txt>Health Systems</BusinessNameLine2Txt>
</TransmitterNameGrp>
<CompanyInformationGrp>
<CompanyNm></CompanyNm>
<MailingAddressGrp>
<USAddressGrp>
<AddressLine1Txt></AddressLine1Txt>
<ns2:CityNm>Rockville</ns2:CityNm>
<USStateCd>MD</USStateCd>
<ns2:USZIPCd></ns2:USZIPCd>
</USAddressGrp>
</MailingAddressGrp>
<ContactNameGrp>
<PersonFirstNm></PersonFirstNm>
<PersonMiddleNm>X</PersonMiddleNm>
<PersonLastNm></PersonLastNm>
</ContactNameGrp>
<ContactPhoneNum></ContactPhoneNum>
</CompanyInformationGrp>
<VendorInformationGrp>
<VendorCd>I</VendorCd>
<ContactNameGrp>
<PersonFirstNm></PersonFirstNm>
<PersonMiddleNm></PersonMiddleNm>
<PersonLastNm></PersonLastNm>
</ContactNameGrp>
<ContactPhoneNum></ContactPhoneNum>
</VendorInformationGrp>
<TotalPayeeRecordCnt>1000</TotalPayeeRecordCnt>
<TotalPayerRecordCnt>1</TotalPayerRecordCnt>
<SoftwareId></SoftwareId>
<FormTypeCd>1094/1095B</FormTypeCd>
<ns2:BinaryFormatCd>application/xml</ns2:BinaryFormatCd>
<ns2:ChecksumAugmentationNum>5bae956d7c6a01c95ce570dd11debe78</ns2:ChecksumAugmentationNum>
<ns2:AttachmentByteSizeNum>5938</ns2:AttachmentByteSizeNum>
<DocumentSystemFileNm>1094B_Request_BBBBB_20151019T121002000Z.xml</DocumentSystemFileNm>
</ACATransmitterManifestReqDtl>
<urn2:ACABusinessHeader wsu:Id="id-1183235E8ED44DE99B069411CD4837DC" xmlns:urn2="urn:us:gov:treasury:irs:msg:acabusinessheader" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<urn:UniqueTransmissionId>d81ead9b-1223-4d28-8d46-f7af58710268:SYS12:BBBBB::T</urn:UniqueTransmissionId>
<urn1:Timestamp>2016-01-27T23:59:36Z</urn1:Timestamp>
</urn2:ACABusinessHeader>
<Action xmlns="http://www.w3.org/2005/08/addressing">RequestSubmissionStatusDetail</Action>
La clave realmente para nosotros fue esta de la documentación del IRS porque estábamos usando Apache CXF v2.1.4:
Big Hack para la codificación del tipo de contenido de 7 bits y el tipo de contenido
5.4.2 (de la documentación del IRS) Tipo de contenido del adjunto de mensajes Los servicios web ISS-A2AAIR requieren que los transmisores usen la mensajería SOAP sobre HTTP con MTOM para enviar archivos de datos XML. El archivo codificado en el archivo adjunto MTOM debe ser XML nativo sin comprimir. El tipo de contenido para el objeto binario codificado MTOM identificado en el encabezado Manifiesto debe ser "application / xml". La codificación de transferencia de contenido del archivo de datos de formulario debe ser de 7 bits.
Dentro de apache-cxf-3.1.4-src / core / src / main / java / org / apache / cxf / attachment / AttachmentSerializer.java
194 private static void writeHeaders(String contentType, String attachmentId,
195 Map<String, List<String>> headers, Writer writer) throws IOException {
196 // writer.write("/r/nContent-Type: ");
197 // writer.write(contentType);
198 writer.write("/r/nContent-Type: application/xml");
199 // writer.write("/r/nContent-Transfer-Encoding: binary/r/n");
200 writer.write("/r/nContent-Transfer-Encoding: 7bit/r/n");
Prabhat, creo que MTOM y SwA no pueden ir de la mano. Puedes usar cualquiera de ellos. Cuando habilita MTOM, no puede usar las API de archivos adjuntos (SwA).