0

我们正在尝试使用 CXF 向 IRS 发送一个签名的、部分加密的 SOAP 消息。我们认为我们正在遵循他们的所有指示,但存在模棱两可的地方。一些 Signature 和 Encryption 属性可以通过多种方式设置,但我尝试过的所有排列都没有让我们摆脱可怕的“TPE1122”错误(WS Security Header 无效)。如果有人成功地做到了这一点,是否有一些我们没有设置的属性?我特别不确定加密算法设置以及是否应该加密整个元素或仅加密其中的 3 个标头元素。谢谢。

    BulkRequestTransmitterService ss = new BulkRequestTransmitterService(wsdlURL, SERVICE_NAME);
    BulkRequestTransmitterPortType port = ss.getBulkRequestTransmitterPort();

    org.apache.cxf.endpoint.Client client = ClientProxy.getClient(port);

    // set up MTOM
    Binding binding = ((BindingProvider)port).getBinding();
    ((SOAPBinding)binding).setMTOMEnabled(true);

    // set output properties
    Map<String, Object> outProps = new HashMap<String, Object>();
    outProps.put("action", "Timestamp Signature Encrypt");
    outProps.put("passwordType", "PasswordDigest");
    outProps.put("signatureUser", "[REDACTED]";
    outProps.put(WSHandlerConstants.SIG_KEY_ID, "X509KeyIdentifier"); 
    outProps.put("passwordCallbackClass", "UTPasswordCallback"); 
    outProps.put("encryptionUser", "irs"); 
    outProps.put("encryptionPropFile", "encryption.properties");
    outProps.put("encryptionKeyIdentifier", "DirectReference"); 
    outProps.put("encryptionKeyTransportAlgorithm", "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p");

    // ENC_SYM_ALGO: what is the default?  what should correct value be?  and are these two lines equivalent?
    outProps.put(WSHandlerConstants.ENC_SYM_ALGO, WSConstants.TRIPLE_DES);  
    outProps.put("encryptionSymAlgorithm", "http://www.w3.org/2001/04/xmlenc#tripledes-cbc");

    // do we encrypt each of the three signed headers, or entire Signature element?  have tried it both ways
    outProps.put("encryptionParts",
        //"{Element}{" + WSU_NS + "}Timestamp;"
        //+"{Element}{urn:us:gov:treasury:irs:ext:aca:air:7.0}ACATransmitterManifestReqDtl;"
        //+"{Element}{urn:us:gov:treasury:irs:ext:aca:air:7.0}ACABusinessHeader;");
        "{Element}{http://www.w3.org/2000/09/xmldsig#}Signature;");

    outProps.put("signaturePropFile", "signature.properties");
    outProps.put("signatureAlgorithm", "http://www.w3.org/2000/09/xmldsig#rsa-sha1");
    outProps.put("signatureParts",
            "{Element}{" + WSU_NS + "}Timestamp;"
            + "{Element}{urn:us:gov:treasury:irs:ext:aca:air:7.0}ACATransmitterManifestReqDtl;"
            + "{Element}{urn:us:gov:treasury:irs:ext:aca:air:7.0}ACABusinessHeader;");  
    outProps.put(WSHandlerConstants.SIG_C14N_ALGO, "http://www.w3.org/2001/10/xml-exc-c14n#WithComments");

    // is "Direct Reference" preferable?  have tried it both ways
    outProps.put(WSHandlerConstants.ENC_KEY_ID, "X509KeyIdentifier"); 

    outProps.put("timeToLive", "600");  // = 10 min
    outProps.put(WSHandlerConstants.MUST_UNDERSTAND, "false");

    WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
    client.getOutInterceptors().add(wssOut); 

    // add gzip interceptor  
    GZIPOutInterceptor gz = new GZIPOutInterceptor();
    gz.setForce(true); 
    client.getOutInterceptors().add(gz);

    [ create & populate Manifest Detail here]

    Header detailHeader = new Header(new QName("urn:us:gov:treasury:irs:ext:aca:air:7.0", "ACATransmitterManifestReqDtl"), aCATrnsmtManifestReqDtlType,
            new JAXBDataBinding(ACATrnsmtManifestReqDtlType.class));
    headers.add(detailHeader);  

    Header businessHeader = new Header(new QName("urn:us:gov:treasury:irs:ext:aca:air:7.0", "ACABusinessHeader"), aCABulkBusinessHeaderRequestType,
                                    new JAXBDataBinding(ACABulkBusinessHeaderRequestType.class));
    headers.add(businessHeader);

    // add headers to Request
    client.getRequestContext().put(Header.HEADER_LIST, headers); 

    // add namespaces:
    Map<String, String> nsMap = new HashMap<>();
    nsMap.put("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");  
    nsMap.put("urn", "urn:us:gov:treasury:irs:ext:aca:air:7.0");
    nsMap.put("urn1", "urn:us:gov:treasury:irs:common");        
    nsMap.put("urn2", "urn:us:gov:treasury:irs:msg:acabusinessheader");
    nsMap.put("urn3", "urn:us:gov:treasury:irs:msg:irsacabulkrequesttransmitter");
    nsMap.put("urn4", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
    client.getRequestContext().put("soap.env.ns.map", nsMap); 

    // then transmit, get TPE1122 error in Response
4

2 回答 2

1

Bulit in CXF security will not work in IRS submission. You need to code your interceptors for matching IRS requirements.

I have a sample project ready, which can do submission and status requests. This is by no means a production code, but can be a starting point

https://github.com/sangramjadhav/irsclient

Please see application.yml file. You need to provide keystore and other configuration for submission to IRS

于 2016-05-30T07:11:21.833 回答
0

感谢两位响应者的反馈。我们现在可以使用它,主要问题是我们不应该使用加密。我发布的示例中的所有内容都有效(包括使用 CXF 对标头的某些部分进行签名),但必须删除加密。

传输到 IRS AIR 系统时,确实很难把所有事情都做好。下一个障碍是通过更改其中一个 wsdl 生成的文件中的命名空间来解决的,然后它通过了,但是他们的 Linux 系统的文件大小值比我们的 Windows 系统的值小 2 个字符 - 罪魁祸首是尾随的 CRLF。

如果有人像我们一样尝试这样做,使用 Java、Apache-CXF 和 Windows,我很乐意回答具体问题。

于 2016-06-16T23:48:02.863 回答