我使用WSS4J 2.1.10对带有时间戳的soap消息进行签名。
我要向其发送消息的服务要求
1)在签名、时间戳、BST元素中包含命名空间http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512
2)将"wsu“名称空间添加到时间戳元素的转换的InclusiveNamespaces PrefixList中,如下所示:
<ds:Reference URI="#TS-634a1acd-e8fd-4629-a19a-1935e677797b">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="wsu wsse env"/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>uDqH4tK4HcsJWOit+DUW8llsEk8=</ds:DigestValue>
</ds:Reference> 3)将签名元素的"wsse“命名空间添加到CanonicalizationMethod的InclusiveNamespaces PrefixList,如下所示:
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="wsse env"/>
</ds:CanonicalizationMethod>谁能告诉我这是不是可能的以及如何实现的?
到目前为止我的代码是:
WSSConfig.init();
SOAPMessage soapMessage = getSoapMessage();
SOAPHeader soapHeader = soapMessage.getSOAPHeader();
Name toHeaderName = soapFactory.createName("To", "", "http://www.w3.org/2005/08/addressing");
SOAPHeaderElement toHeader = soapHeader.addHeaderElement(toHeaderName);
toHeader.setAttributeNS(WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":Id", "_5002");//TODO: Does this need to be a fixed value?
Attr idAttr = toHeader.getAttributeNode(WSConstants.WSU_PREFIX + ":Id");
toHeader.setIdAttributeNode(idAttr, true);
toHeader.setTextContent(vgEndpoint);
Name actionHeaderName = soapFactory.createName("Action", "", "http://www.w3.org/2005/08/addressing");
SOAPHeaderElement actionHeader = soapHeader.addHeaderElement(actionHeaderName);
actionHeader.setTextContent("http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue");
actionHeader.setMustUnderstand(true);
Name replyToHeaderName = soapFactory.createName("ReplyTo", "", "http://www.w3.org/2005/08/addressing");
SOAPHeaderElement replyToHeader = soapHeader.addHeaderElement(replyToHeaderName);
Name rtAddressName = soapFactory.createName("Address");
SOAPElement rtAddress = replyToHeader.addChildElement(rtAddressName);
rtAddress.setTextContent("http://www.w3.org/2005/08/addressing/anonymous");
Name faultToHeaderName = soapFactory.createName("FaultTo", "", "http://www.w3.org/2005/08/addressing");
SOAPHeaderElement faultToHeader = soapHeader.addHeaderElement(faultToHeaderName);
Name ftAddressName = soapFactory.createName("Address");
SOAPElement ftAddress = faultToHeader.addChildElement(ftAddressName);
ftAddress.setTextContent("http://www.w3.org/2005/08/addressing/anonymous");
Name messageIdName = soapFactory.createName("MessageID", "", "http://www.w3.org/2005/08/addressing");
SOAPHeaderElement messageIdHeader = soapHeader.addHeaderElement(messageIdName);
messageIdHeader.setTextContent("uuid:" + UUID.randomUUID().toString());
Name secHeaderName = soapFactory.createName(WSConstants.WSSE_LN, WSConstants.WSSE_PREFIX, WSConstants.WSSE_NS);
SOAPHeaderElement secHeader = soapHeader.addHeaderElement(secHeaderName);
secHeader.addNamespaceDeclaration("wsc", "http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512");
secHeader.setMustUnderstand(true);
Merlin crypto = getCrypto(privateKey, password, salt, certChain);
Document unsignedDocument = soapMessage.getSOAPPart().getEnvelope().getOwnerDocument();
WSSecHeader wsSecHeader = new WSSecHeader(unsignedDocument);
wsSecHeader.insertSecurityHeader();
WSSecTimestamp timestamp = new WSSecTimestamp();
timestamp.setPrecisionInMilliSeconds(false);
timestamp.setTimeToLive(600);
timestamp.build(unsignedDocument, wsSecHeader);
// Setup the signer
WSSecSignature signer = new WSSecSignature();
signer.setUserInfo("signingCert", password);
signer.setSignatureAlgorithm(WSConstants.RSA_SHA1);
signer.setDigestAlgo(WSConstants.SHA1);
signer.setSigCanonicalization(WSConstants.C14N_EXCL_OMIT_COMMENTS);
signer.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
signer.setAddInclusivePrefixes(true);
signer.setUseSingleCertificate(true);
signer.getParts().add(new WSEncryptionPart("Timestamp", WSConstants.WSU_NS, null));
signer.getParts().add(new WSEncryptionPart("To", "http://www.w3.org/2005/08/addressing", null));
signer.build(unsignedDocument, crypto, wsSecHeader);以下是生成的Soap消息,显然缺少这3点:
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
<env:Header>
<To xmlns="http://www.w3.org/2005/08/addressing" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="_5002">https://localhost/service.svc</To>
<Action xmlns="http://www.w3.org/2005/08/addressing" env:mustUnderstand="true">http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue</Action>
<ReplyTo xmlns="http://www.w3.org/2005/08/addressing">
<Address>http://www.w3.org/2005/08/addressing/anonymous</Address>
</ReplyTo>
<FaultTo xmlns="http://www.w3.org/2005/08/addressing">
<Address>http://www.w3.org/2005/08/addressing/anonymous</Address>
</FaultTo>
<MessageID xmlns="http://www.w3.org/2005/08/addressing">uuid:dc08272f-609f-47e3-ac9b-6049a98a0dab</MessageID>
<wsse:Security 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" env:mustUnderstand="true">
<wsse:BinarySecurityToken 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" wsu:Id="X509-848ca3b0-a273-4cbf-ae1a-e34dc570444e">*** REMOVED ***</wsse:BinarySecurityToken>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="SIG-25253839-097b-495a-ae60-24fa8a5f0ada">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="env"/>
</ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#TS-634a1acd-e8fd-4629-a19a-1935e677797b">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="wsse env"/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>uDqH4tK4HcsJWOit+DUW8llsEk8=</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#_5002">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="env"/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>LiNgJUCK0GyrUZ3BpbdlRbVKnfo=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>l8EyofVcLesFD1c6btPu2zJ6dTRTyqCSWy7aW7MVH4x3nWh3y0Ir7xY2nNSZeXpcc5Q/7wrWOVgX+TkT/zwEVL62hpq4HyUJb/aIwTDhUIlH5UL7UeudDCRvvAnPOtzEp/jnapKUbsJpIzXWmvlS6tB2E3SUDT/MChradRcawJ0=</ds:SignatureValue>
<ds:KeyInfo Id="KI-c2995ba4-6fe5-457c-9367-25c5d98eff91">
<wsse:SecurityTokenReference wsu:Id="STR-4bc8eb55-9b1f-4bb8-a7cc-d4685bd3aa2c">
<wsse:Reference URI="#X509-848ca3b0-a273-4cbf-ae1a-e34dc570444e" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
<wsu:Timestamp wsu:Id="TS-634a1acd-e8fd-4629-a19a-1935e677797b">
<wsu:Created>2017-07-11T02:38:06Z</wsu:Created>
<wsu:Expires>2017-07-11T02:48:06Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</env:Header>
<env:Body/>
</env:Envelope>发布于 2018-03-05 22:25:47
我是这么做的
List<String> prefixList = new ArrayList<String>();
prefixList.add("ser soapenv");
sigFactory.newCanonicalizationMethod(CanonicalizationMethod.EXCLUSIVE,new ExcC14NParameterSpec(prefixList));结果
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"> <InclusiveNamespaces xmlns="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="ser soapenv"/> </ds:CanonicalizationMethod>
https://stackoverflow.com/questions/45024581
复制相似问题