签署 JAX-WS SOAP 请求
我想编写一个 JAX-WS Web 服务,使用 http://www.w3.org 签署我的 SOAP 消息/TR/xmldsig-core/ 推荐。
根据我在互联网上找到的内容,我编写了一个 JAX-WS 处理程序 (SOAPHandler
),它设法更改 SOAP 请求的副本:
@Override
public boolean handleMessage(SOAPMessageContext smc) {
Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
SOAPMessage message = smc.getMessage();
if (outboundProperty) {
try {
SOAPPart soapPart = message.getSOAPPart();
SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
Source source = soapPart.getContent();
Node root = null;
Document doc22 = null;
if (source instanceof DOMSource) {
root = ((DOMSource) source).getNode();
} else if (source instanceof SAXSource) {
InputSource inSource = ((SAXSource) source).getInputSource();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = null;
db = dbf.newDocumentBuilder();
doc22 = db.parse(inSource);
root = (Node) doc22.getDocumentElement();
}
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
Reference ref = fac.newReference("", fac.newDigestMethod(DigestMethod.SHA1, null),
Collections.singletonList(fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)),
null, null);
SignedInfo si = fac.newSignedInfo(fac.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE,
(C14NMethodParameterSpec) null),
fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
Collections.singletonList(ref));
// Load the KeyStore and get the signing key and certificate.
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("client_keystore.jks"), "changeit".toCharArray());
KeyStore.PrivateKeyEntry keyEntry =
(KeyStore.PrivateKeyEntry) ks.getEntry("client", new KeyStore.PasswordProtection("changeit".toCharArray()));
X509Certificate cert = (X509Certificate) keyEntry.getCertificate();
// Create the KeyInfo containing the X509Data.
KeyInfoFactory kif2 = fac.getKeyInfoFactory();
List x509Content = new ArrayList();
x509Content.add(cert.getSubjectX500Principal().getName());
x509Content.add(cert);
X509Data xd = kif2.newX509Data(x509Content);
KeyInfo ki = kif2.newKeyInfo(Collections.singletonList(xd));
Element header = getFirstChildElement(root/*.getDocumentElement()*/);
DOMSignContext dsc = new DOMSignContext(keyEntry.getPrivateKey(), header /*doc.getDocumentElement()*/);
XMLSignature signature = fac.newXMLSignature(si, ki);
signature.sign(dsc);
//TODO: change this to update the SOAP message, not write it to disks
OutputStream os = new FileOutputStream("out.xml");
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
trans.transform(new DOMSource(root), new StreamResult(os));
} catch (Exception ex) {
System.out.println(ex);
}
}
return true;
}
但我不知道如何更新 SOAP要求?
I would like to write a JAX-WS web service that signs my SOAP messages using the http://www.w3.org/TR/xmldsig-core/ recommendation.
With what I found on the internet I wrote a JAX-WS handler (SOAPHandler<SOAPMessageContext>
) that manages to change a copy of the SOAP request:
@Override
public boolean handleMessage(SOAPMessageContext smc) {
Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
SOAPMessage message = smc.getMessage();
if (outboundProperty) {
try {
SOAPPart soapPart = message.getSOAPPart();
SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
Source source = soapPart.getContent();
Node root = null;
Document doc22 = null;
if (source instanceof DOMSource) {
root = ((DOMSource) source).getNode();
} else if (source instanceof SAXSource) {
InputSource inSource = ((SAXSource) source).getInputSource();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = null;
db = dbf.newDocumentBuilder();
doc22 = db.parse(inSource);
root = (Node) doc22.getDocumentElement();
}
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
Reference ref = fac.newReference("", fac.newDigestMethod(DigestMethod.SHA1, null),
Collections.singletonList(fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)),
null, null);
SignedInfo si = fac.newSignedInfo(fac.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE,
(C14NMethodParameterSpec) null),
fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
Collections.singletonList(ref));
// Load the KeyStore and get the signing key and certificate.
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("client_keystore.jks"), "changeit".toCharArray());
KeyStore.PrivateKeyEntry keyEntry =
(KeyStore.PrivateKeyEntry) ks.getEntry("client", new KeyStore.PasswordProtection("changeit".toCharArray()));
X509Certificate cert = (X509Certificate) keyEntry.getCertificate();
// Create the KeyInfo containing the X509Data.
KeyInfoFactory kif2 = fac.getKeyInfoFactory();
List x509Content = new ArrayList();
x509Content.add(cert.getSubjectX500Principal().getName());
x509Content.add(cert);
X509Data xd = kif2.newX509Data(x509Content);
KeyInfo ki = kif2.newKeyInfo(Collections.singletonList(xd));
Element header = getFirstChildElement(root/*.getDocumentElement()*/);
DOMSignContext dsc = new DOMSignContext(keyEntry.getPrivateKey(), header /*doc.getDocumentElement()*/);
XMLSignature signature = fac.newXMLSignature(si, ki);
signature.sign(dsc);
//TODO: change this to update the SOAP message, not write it to disks
OutputStream os = new FileOutputStream("out.xml");
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
trans.transform(new DOMSource(root), new StreamResult(os));
} catch (Exception ex) {
System.out.println(ex);
}
}
return true;
}
But I can't figure out how to update the SOAP request?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我为 Soap 请求的 Xml 数字签名开发了 SOAPHandler。
我认为@AndrewBourgeois代码中的问题是获取源代码的方式。
问候,
I develop a SOAPHandler for Xml Digital Signature of Soap Request.
I think the problem in code of @AndrewBourgeois is the way of get Source.
Regards,
最简单的方法是使用应用程序服务器中集成的功能。例如:通过 WebSphere App Server 使用消息级安全性来保护 JAX-WS Web 服务
如何在 WAS 上配置签名,您可以找到这里。
这里是有关配置消息级安全性的WebLogic文档 。
The simplest way is to use functionality integrated in application server. For example :Securing JAX-WS Web services using message-level security with WebSphere App Server
How to configure signing on WAS you can find here.
And here is WebLogic documentation about Configuring Message-Level Security.
您可以尝试soapPart.saveChanges();
You can try soapPart.saveChanges();
在代码行之后:
插入此语句:
它将保存您的更改。
After the code line:
insert this statement:
It will save your changes.