首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >IRS Soap故障-无效的WS安全报头

IRS Soap故障-无效的WS安全报头
EN

Stack Overflow用户
提问于 2016-01-22 08:59:09
回答 2查看 3.2K关注 0票数 2

我正试图向IRS发送一个Soap请求,并且和这个组中的其他人一样面临相同的错误--“无效的WS安全头”。有人能用一个示例Soap请求来指导我吗?另一个问题是--作为注册过程的一部分,我们向国税局网站提交了我们的X509证书(公钥),该证书将用于认证/解密您的邮件摘要。您为此过程上载了哪些证书文件?我们现在真的被这个错误困住了好几天。感谢你在这方面的任何帮助。我见过两个关于这个题目的问题,但没有任何帮助的答案。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-23 03:42:58

我假设这是为ACA航空国税局提交的。我们将.cer文件上传到美国国税局网站,在那里,您将您的TCC (例如,BBBBB格式)与您上传的.cer相关联。我们使用的堆栈是:Oracle的JDK 8、WSS4J v2.1.4和CXFv3.1.4。下面是用于对IRS希望签名的引用元素签名的示例Java代码:

代码语言:javascript
复制
 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;
}

下面是示例SOAP请求

代码语言:javascript
复制
<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>

对我们来说,关键在于IRS文档中的这一点,因为我们使用的是Apache v2.1.4:

7位内容类型编码和内容类型的大哈克

5.4.2 (来自IRS文档)消息附件内容类型ISS-A2AAIR web服务要求发射机使用带有MTOM的SOAP消息发送XML数据文件。在MTOM附件中编码的文件必须是未压缩的原生XML。Manifest标头中标识的MTOM编码二进制对象的内容类型必须是“application/xml”。表单数据文件的内容传输编码必须是7位.

内部apache-cxf-3.1.4-src/core/src/main/java/org/apache/cxf/attachment/AttachmentSerializer.java

代码语言:javascript
复制
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");
票数 2
EN

Stack Overflow用户

发布于 2016-02-05 17:41:22

牧师,我认为MTOM和SwA不能并驾齐驱。你可以用任何一种。启用MTOM时,不能使用附件API (SwA)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34942628

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档