我是coldfusion程序员,没有JAVA知识经验。
我正在处理一个小项目,从网络服务中获取一些信息。我们正在使用 Coldfusion 服务器 9。
两台服务器的 SSL 证书/密钥库均已设置并且能够相互通信。
但是,对于 SOAP 内容,我们需要使用 WS-security - X.509 证书进行签名和加密。
这是我的 cfm 代码:
<cfhttp
url = "[HTTPS URL]?wsdl"
method ="post"
result ="httpResponse"
charset ="utf-8">
<cfhttpparam
type="header"
name="accept-encoding"
value="no-compression"
/>
<cfhttpparam
type="xml"
value="#trim( soapBody )#"
/>
</cfhttp>
以下是错误消息:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>These policy alternatives can not be satisfied:
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}
AsymmetricBinding: Received Timestamp does not match the requirements
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}
X509Token: The received token does not match the token inclusion requirement
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}
X509Token
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}
InitiatorToken
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}
RecipientToken
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}
IncludeTimestamp: Received Timestamp does not match the requirements
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}
SignedParts: {http://schemas.xmlsoap.org/soap/envelope/}
Body not SIGNED
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}
EncryptedParts:
{http://schemas.xmlsoap.org/soap/envelope/}
Body not ENCRYPTED
</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
下面是供应商提供的示例 SOAP 代码:
1)加密前的 SOAP 内容:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soap="http://soap.ipr.tfp.com/">
<soapenv:Header/>
<soapenv:Body>
<soap:create>
<arg0>
<attribute_1>abc</attribute_1>
<attribute_2></attribute_2>
<attribute_3>abc123</attribute_3>
</arg0>
</soap:create>
</soapenv:Body>
2) 加密后的 SOAP 内容示例 :
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<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" soap:mustUnderstand="1">
<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-A1F720DE139A1F1A4013443711179924">MIIBqDCCARECBFARU1swDQYJKoZIhvcNAQEFBQAwGzEZMBcGA1UEAxMQdGVzdGNs
aWVuddhwDz3irKnXKJK5hjLnxYygMBNAH8w=
</wsse:BinarySecurityToken>
<wsu:Timestamp wsu:Id="TS-1">
<wsu:Created>2012-08-07T20:25:17.950Z</wsu:Created>
<wsu:Expires>2012-08-07T20:30:17.950Z</wsu:Expires>
</wsu:Timestamp>
<xenc:EncryptedKey xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="EK-A1F720DE139A1F1A4013443711180615">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"></xenc:EncryptionMethod>
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<wsse:SecurityTokenReference>
<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/oasis-wss-soap-message-security-1.1#ThumbprintSHA1">DNmvc0YlN1g329Z1BMjGRj4zcz4=</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>ED3EwEOKHYr+Jdc5WtOs6DF3r7E33uRokAnuyjX/PxSQcINrYTrjOdJpN6IJvhuZrmu1I9578575685Z2mtjT/XmI9CQohLl6XmzpSdHwf70tTrsKDmpDt8HM4XPPs=</xenc:CipherValue>
</xenc:CipherData>
<xenc:ReferenceList>
<xenc:DataReference URI="#ED-3"></xenc:DataReference>
</xenc:ReferenceList>
</xenc:EncryptedKey>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="SIG-2">
<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="soap">
</ec:InclusiveNamespaces>
</ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1">
</ds:SignatureMethod>
<ds:Reference URI="#TS-1">
<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 soap"></ec:InclusiveNamespaces>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1">
</ds:DigestMethod>
<ds:DigestValue>e779ZcX0K3nc9W+Y4lzyw7KR04c=</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#Id-4919785">
<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=""></ec:InclusiveNamespaces>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
<ds:DigestValue>HHHpB67969I7BEUc=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>06t2b5COp/70OcIv4HFwO4gKILZntbleryqGNtuRMOfUbtOJU9etyetryertyxRu4LVZH7o5I=</ds:SignatureValue>
<ds:KeyInfo Id="KI-A1F720DE139A1F1A4013443711179852">
<wsse:SecurityTokenReference wsu:Id="STR-A1F720DE139A1F1A4013443711179883">
<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/oasis-wss-soap-message-security-1.1#ThumbprintSHA1">mouSxMr4bYmR+cnkJWMyR1ymRe8=</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
</wsse:Security>
</soap:Header>
<soap:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-206789689ty-utility-1.0.xsd" wsu:Id="Id-4919785">
<xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="ED-3" Type="http://www.w3.org/2001/04/xmlenc#Content">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"></xenc:EncryptionMethod>
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey">
<wsse:Reference URI="#EK-A1F720DE13896795">
</wsse:Reference>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>9Qpzj1y6EoyT9IRJZv+MF2OjxDwOY354643563456pnBD2OY7qZqb3knYLE+r3c/2fgxRpjrcKkMTYUUXQvw5467547567p354636+dd+y16OSAwicS6pyqb7eVwP33563565AfcGq0qnWsFNNJ3WX3PEO7JeKPI
</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</soap:Body>
</soap:Envelope>
以下是供应商提供的JAVA文件。
Client.java
package com.tfp.ipr.soap;
/**
* Please modify this class to meet your needs
* This class is not complete
*/
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;
import java.util.ArrayList;
import java.util.List;
/**
* This class was generated by Apache CXF 2.4.8 2012-07-24T10:21:51.038-05:00
* Generated source version: 2.4.8
*
*/
public final class Client {
private static final QName SERVICE_NAME = new QName("http://soap.ipr.tfp.com/", "WsiprService");
private Client() {
}
public static void main(String args[]) throws java.lang.Exception {
URL wsdlURL = WsiprService.WSDL_LOCATION;
if (args.length > 0 && args[0] != null && !"".equals(args[0])) {
File wsdlFile = new File(args[0]);
try {
if (wsdlFile.exists()) {
wsdlURL = wsdlFile.toURI().toURL();
} else {
wsdlURL = new URL(args[0]);
}
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
WsiprService ss = new WsiprService(wsdlURL, SERVICE_NAME);
Helpme port = ss.getWsiprPort();
if ("validate".equals(args[1])) {
System.out.println("Invoking validate...");
java.lang.String _validate_arg0 = args[2];
com.tfp.ipr.soap.ResultDetail _validate__return = port.validate(_validate_arg0);
print(_validate__return);
//System.out.println("validate.result="
// + _validate__return.getInstitutionDetail().getAccountNo());
}
else if ("create".equals(args[1])) {
System.out.println("Invoking create...");
com.tfp.ipr.soap.CreationRequest _create_arg0 = new com.tfp.ipr.soap.CreationRequest();
_create_arg0.setAttribute_1(args[5]);
_create_arg0.setAttribute_2(args[6]);
_create_arg0.setAttribute_3(args[3]);
com.tfp.ipr.soap.ResultDetail _create__return = port.create(_create_arg0);
print(_create__return);
}
System.exit(0);
}
public static void print(com.tfp.ipr.soap.ResultDetail r) {
System.out.println("\n\n getInstitutionDetail_A: " + r.getInstitutionDetail().getInstitutionDetail_A());
System.out.println(" getInstitutionDetail_B: " + r.getInstitutionDetail().getInstitutionDetail_B());
System.out.println(" getInstitutionDetail_C: " + r.getInstitutionDetail().getInstitutionDetail_C());
List l = r.getExceptionDetails().getExceptionList();
System.out.println();
for(int i=0; i < l.size(); i++) {
ExceptionDetail exceptionDetail = (ExceptionDetail)l.get(i);
System.out.println(" Exception code: " + exceptionDetail.getCode());
System.out.println(" Exception Message: " + exceptionDetail.getMessage());
}
}
}
这里有人可以给我一些指导或告诉我如何将上述 JAVA 文件实现到 Coldfusion 中,或者如何将上述 JAVA 文件逆向工程到 CFM scipt 中?
这是我发现的一些研究,不确定是否对我的问题有帮助:
非常感谢您的帮助。
迟到了......但这里有关于如何做到这一点的代码示例。您手动构建 Soap 消息并将其传递给函数。
香皂上:身体套装
function signXML (string xml_doc) {
var keystoreType = "JKS";
var keystorePass = "password";
var privateKeyAlias = "certalias";
var privateKeyPass = "password";
var certificateAlias = "certalias";
var KeyStorePath = ExpandPath("./yourKeystore.jks");
//Initialize xml security
// this need becuase Init has sepecial meaning in ColdFusion
XMLSecurityInit = createObject("java", "org.apache.xml.security.Init");
// initialize if needed
if (!XMLSecurityInit.isInitialized()) {
// find static method named "init" with no parameters
method = XMLSecurityInit.getClass().getDeclaredMethod("init", []);
// invoke it via reflection
method.invoke(XMLSecurityInit, javacast("null", ""));
}
// Prepare for XML Parsing
dbFactory = CreateObject("java", "javax.xml.parsers.DocumentBuilderFactory").newInstance();
dbFactory.setNamespaceAware(true);
dbFactory.setValidating(true);
dbFactory.setIgnoringComments(true);
dBuilder = dbFactory.newDocumentBuilder();
dBuilder.setErrorHandler(CreateObject("java", "org.apache.xml.security.utils.IgnoreAllErrorHandler").init());
// Parse the XML string to a Document
ByteArrayInputStream = CreateObject("java", "java.io.ByteArrayInputStream").init(xml_doc.getBytes());
doc = dBuilder.parse(ByteArrayInputStream);
// Get the Kestore.
var ks = createObject("java", "java.security.KeyStore").getInstance("JKS");
var fileInputStream = createObject("java", "java.io.FileInputStream").init(KeyStorePath);
ks.load(fileInputStream, keystorePass.toCharArray());
fileInputStream.close();
// Get private key and certificate
privateKey = ks.getKey(privateKeyAlias, privateKeyPass.toCharArray());
x509Cert = ks.getCertificate(certificateAlias);
nodes = doc.getElementsByTagName("soap:Header");
headerElement = nodes.item(0);
body_nodes = doc.getElementsByTagName("soap:Body");
bodyElement = body_nodes.item(0);
// Must define the ID attribute... can be anything... like foo or Id.
// https://stackoverflow.com/questions/53043668/getelementbyid-return-null-for-xml-document-in-java
bodyElement.setIdAttribute("Id",true);
ElementProxy = CreateObject("java", "org.apache.xml.security.utils.ElementProxy");
ElementProxy.setDefaultPrefix("http://www.w3.org/2000/09/xmldsig##", "");
soapsec = doc.createElementNS("", "SOAP-SEC:Signature");
soapsec.setAttributeNS("", "mustUnderstand", "1");
soapsec.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:SOAP-SEC",
"http://www.schemas.xmlsoap.org/soap/security/2000-12");
// Create an instance of the Transforms class
Transforms = CreateObject("java", "org.apache.xml.security.transforms.Transforms");
Transforms.init(doc);
Transforms.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
// Create an instance of the XMLSignature class
XMLSignature = CreateObject("java", "org.apache.xml.security.signature.XMLSignature");
sig = XMLSignature.init(doc, "", XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1);
soapsec.appendChild(sig.getElement());
headerElement.appendChild(soapsec);
Constants = CreateObject("java", "org.apache.xml.security.utils.Constants");
sig.addDocument("##Body", transforms, Constants.ALGO_ID_DIGEST_SHA1);
cert = ks.getCertificate(certificateAlias);
data = CreateObject("java", "org.apache.xml.security.keys.content.X509Data").init(doc);
data.addIssuerSerial(cert.getIssuerDN().getName(), cert.getSerialNumber());
// Get KeyInfo from the XMLSignature and add X509Data to it
info = sig.getKeyInfo();
info.add(data);
dumpdocument(doc);
// Sign the document
sig.sign(privateKey);
// Output the signed document to a ByteArrayOutputStream
ByteArrayOutputStream = CreateObject("java", "java.io.ByteArrayOutputStream").init();
XMLUtils = CreateObject("java", "org.apache.xml.security.utils.XMLUtils");
XMLUtils.outputDOM(doc, ByteArrayOutputStream);
// Optional: Convert ByteArrayOutputStream to a byte array if needed
signedMessage = ByteArrayOutputStream.toString();
return signedMessage;
}