新對我來說:我需要使用提供者頒發的證書對來自ColdFusion客戶端應用程序的SOAP請求主體進行數字簽名和加密。我也需要解密響應才能處理它。如何在ColdFusion中對SOAP請求BODY進行數字簽名?
我已經搜索了幾天沒有找到任何東西。我發現了引用其他語言的信息,但在ColdFusion中沒有任何信息。如果無法通過ColdFusion語言API本地執行此操作,有人可以通過「createObject()」函數或任何其他方法幫助我調用正確的Java或.net類嗎?
17SEP2012 - 附加信息:
更多信息:後超時,而我一直在尋找的代碼。這裏是完整的帖子:
我正在使用Web服務,而不是提供一個。我已經達到了將整個事情都工作的地步,但它只能通過ColdFusion「createObject」調用一次。
仍然需要幫助。系統:帶有ColdFusion 9單服務器安裝的Windows Server 2003。
我使用了Apache的wss4J庫,並編寫了一個簡單的Java類作爲入口點。自定義Java類僅將完整的SOAP消息作爲String參數,將String傳遞給wss4j DateStamp類,然後將生成的SOAP部分對象傳遞給簽名類,然後傳遞加密類。然後它通過PrettyDocumentToString函數返回已簽名和加密的SOAP信封,該信封已從文檔(SOAP部分)轉換爲字符串。
所有這些工作,我得到一個帶有安全標頭和簽名,加密機構的SOAP信封。問題是,在重新啓動ColdFusion服務(在Windows Server 2003上安裝單個服務器)後,它全部運行一次,但後續運行會導致在wss4j簽名代碼中發生錯誤。我甚至使用Winmerge來比較整個ColdFusion9目錄,緊接着第一次運行後立即和第二次運行後立即重新啓動。唯一的區別是在日誌文件中。 ColdFusion9 \ lib \ neo-datasource.xml文件中存在差異,但只是按照幾個數據源描述符的順序,而不是內容。
下面是代碼和堆棧跟蹤:
writeOutputs and writeDumps are only for visualization during debugging.
的ColdFusion調用腳本:
<cfscript>
variables.tempPath = getDirectoryFromPath(getCurrentTemplatePath());
variables.filePath = tempPath & "ASI_source_request_example.xml";
variables.fileContent = FileRead(filePath);
writeOutput("FILECONTENT: <br>");
writeOutput("variables.fileContent);
writeDump(var="#variables.fileContent#", format="html", output="#expandPath('./')#_DUMP-OUTPUT.htm");
variables.encSOAP=createobject("java","ProcessIDSRSSOAP").runProcess(fileContent);
writeOutput("<br><br>encSOAP: <br>");
writeOutput(variables.encSOAP);
writeDump(var="#variables.encSOAP#", format="html", output="#expandPath('./')#_DUMP-OUTPUT.htm");
</cfscript>
Java類:
import java.io.FileReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.apache.ws.security.SOAPConstants;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSEncryptionPart;
import org.apache.ws.security.WSSConfig;
import org.apache.ws.security.common.SOAPUtil;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.components.crypto.CryptoFactory;
import org.apache.ws.security.message.WSSecEncrypt;
import org.apache.ws.security.message.WSSecHeader;
import org.apache.ws.security.message.WSSecSignature;
import org.apache.ws.security.message.WSSecTimestamp;
import org.apache.ws.security.util.WSSecurityUtil;
import org.w3c.dom.Document;
public class ProcessIDSRSSOAP {
private static Crypto crypto = null;
private static Properties properties = new Properties();
private static String user = "";
private static String cryptoPwd = "";
private static WSSecSignature builder = new WSSecSignature();
private static SOAPConstants soapConstants = null;
private final WSSecHeader secHeader = new WSSecHeader();
private Document tsDoc = null;
private Document signedDoc = null;
private Document encryptedDoc = null;
private static final org.apache.commons.logging.Log LOG = org.apache.commons.logging.LogFactory
.getLog(ProcessIDSRSSOAP.class);
public ProcessIDSRSSOAP() throws Exception {
WSSConfig.init();
}
/*
* public static void main(String[] args) throws Exception {
* ProcessIDSRSSOAP processor = new ProcessIDSRSSOAP();
* processor.runProcess(args[0]); }
*/
public String runProcess(String inDoc) throws Exception {
// ProcessIDSRSSOAP processor = new ProcessIDSRSSOAP();
// LOG.debug(inDoc);
Class<ProcessIDSRSSOAP> thisClass = ProcessIDSRSSOAP.class;
ClassLoader thisLoader = thisClass.getClassLoader();
URL propertiesURL = thisLoader.getResource("crypto.properties");
String propertiesPath = propertiesURL.getPath();
propertiesPath = propertiesPath.replaceAll("%20", " ");
properties.load(new FileReader(propertiesPath));
user = properties
.getProperty("org.apache.ws.security.crypto.merlin.keystore.alias");
cryptoPwd = properties
.getProperty("org.apache.ws.security.crypto.merlin.keystore.password");
crypto = CryptoFactory.getInstance("crypto.properties");
builder.setUserInfo(user, cryptoPwd);
builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
SOAPUtil.toSOAPPart(inDoc.trim());
Document PKIDoc = processDoc(inDoc);
String PKIDocString = org.apache.ws.security.util.XMLUtils
.PrettyDocumentToString(PKIDoc);
LOG.debug(PKIDocString);
return PKIDocString;
}
/**
* @param SOAPMsg
* The entire SOAP message as a type String
* @throws Exception
*/
public Document processDoc(String SOAPMsg) throws Exception {
tsDoc = timestampMSG(SOAPMsg);// Time stamp the SOAP String and make it
// a Document type.
secHeader.insertSecurityHeader(tsDoc);// Insert the security header.
soapConstants = WSSecurityUtil.getSOAPConstants(tsDoc
.getDocumentElement());
signedDoc = signBody(tsDoc);// Send the Document on for signing.
encryptedDoc = encryptBody(signedDoc);
return encryptedDoc;
}
/**
* @param msg
* The entire SOAP message as a type String
* @throws Exception
*/
public Document timestampMSG(String msg) throws Exception {
Document doc = SOAPUtil.toSOAPPart(msg);
WSSecHeader secHeader = new WSSecHeader();
secHeader.insertSecurityHeader(doc);
WSSecTimestamp timestamp = new WSSecTimestamp();
timestamp.setTimeToLive(300);
Document createdDoc = timestamp.build(doc, secHeader);
return createdDoc;
}
/**
* @param doc
* Expects a SOAP message as a type Document
* @throws Exception
*/
public Document signBody(Document doc) throws Exception {
List<WSEncryptionPart> parts = new ArrayList<WSEncryptionPart>();
WSEncryptionPart encP = new WSEncryptionPart(soapConstants
.getBodyQName().getLocalPart(), soapConstants.getEnvelopeURI(),
"");
parts.add(encP);
builder.setParts(parts);
Document signedDoc = builder.build(doc, crypto, secHeader);
return signedDoc;
}
public Document encryptBody(Document doc) throws Exception {
SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(doc
.getDocumentElement());
WSSecEncrypt encrypt = new WSSecEncrypt();
encrypt.setUserInfo(user, cryptoPwd);
encrypt.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
WSSecHeader secHeader = new WSSecHeader();
secHeader.insertSecurityHeader(doc);
List<WSEncryptionPart> parts = new ArrayList<WSEncryptionPart>();
WSEncryptionPart encP = new WSEncryptionPart(soapConstants
.getBodyQName().getLocalPart(), // define the body
soapConstants.getEnvelopeURI(), "");
parts.add(encP);
encrypt.setParts(parts);
Document encryptedDoc = encrypt.build(doc, crypto, secHeader);
return encryptedDoc;
}
}
ColdFusion的錯誤:
Signature creation failed (Cannot setup signature data structure)
The error occurred in G:/Inetpub/wwwroot/SOAP/index.cfm: line 14
12 : writeDump(var="#variables.fileContent#", format="html", output="#expandPath('./')#_DUMP-OUTPUT.htm");
13 :
14 : variables.encSOAP=createobject("java","ProcessIDSRSSOAP").runProcess(fileContent);
15 :
16 : writeOutput("<br><br>encSOAP: <br>");
堆棧跟蹤:
at cfindex2ecfm1134068877.runPage(G:/Inetpub/wwwroot/SOAP/index.cfm:14)
org.apache.ws.security.WSSecurityException: Signature creation failed (Cannot setup signature data structure)
at org.apache.ws.security.message.WSSecSignatureBase.addReferencesToSign(WSSecSignatureBase.java:191)
at org.apache.ws.security.message.WSSecSignature.addReferencesToSign(WSSecSignature.java:409)
at org.apache.ws.security.message.WSSecSignature.build(WSSecSignature.java:381)
at ProcessIDSRSSOAP.signBody(ProcessIDSRSSOAP.java:118)
at ProcessIDSRSSOAP.processDoc(ProcessIDSRSSOAP.java:85)
at ProcessIDSRSSOAP.runProcess(ProcessIDSRSSOAP.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at coldfusion.runtime.java.JavaProxy.invoke(JavaProxy.java:97)
at coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:2360)
at cfindex2ecfm1134068877.runPage(G:\Inetpub\wwwroot\SOAP\index.cfm:14)
at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:231)
at coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:416)
at coldfusion.filter.CfincludeFilter.invoke(CfincludeFilter.java:65)
at coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:381)
at coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:48)
at coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40)
at coldfusion.filter.PathFilter.invoke(PathFilter.java:94)
at coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:70)
at coldfusion.filter.BrowserDebugFilter.invoke(BrowserDebugFilter.java:79)
at coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28)
at coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38)
at coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:46)
at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38)
at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22)
at coldfusion.filter.CachingFilter.invoke(CachingFilter.java:62)
at coldfusion.CfmServlet.service(CfmServlet.java:200)
at coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89)
at jrun.servlet.FilterChain.doFilter(FilterChain.java:86)
at coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:42)
at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46)
at jrun.servlet.FilterChain.doFilter(FilterChain.java:94)
at jrun.servlet.FilterChain.service(FilterChain.java:101)
at jrun.servlet.ServletInvoker.invoke(ServletInvoker.java:106)
at jrun.servlet.JRunInvokerChain.invokeNext(JRunInvokerChain.java:42)
at jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:286)
at jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:543)
at jrun.servlet.jrpp.JRunProxyService.invokeRunnable(JRunProxyService.java:203)
at jrunx.scheduler.ThreadPool$DownstreamMetrics.invokeRunnable(ThreadPool.java:320)
at jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:428)
at jrunx.scheduler.ThreadPool$UpstreamMetrics.invokeRunnable(ThreadPool.java:266)
at jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)
Caused by: java.lang.NullPointerException
at org.apache.ws.security.message.DOMCallbackLookup.getElements(DOMCallbackLookup.java:94)
at org.apache.ws.security.util.WSSecurityUtil.findElements(WSSecurityUtil.java:267)
at org.apache.ws.security.message.WSSecSignatureBase.addReferencesToSign(WSSecSignatureBase.java:156)
... 43 more
顯然,事情是從org.apache.ws.security.message.DOMCallbackLookup.getElements丟失。 餵養它的代碼是:
return callbackLookup.getElements(part.getName(),part.getNamespace());
我似乎無法弄清楚,爲什麼它的工作原理,從CF調用時的第一次,但失敗,並在隨後的運行這個錯誤。
您打電話給公衆的API是?服務提供商是否提供其他語言的示例? – barnyr 2012-07-23 13:38:51
該提供者位於一個安全的政府網絡。他們沒有例子。 – user1172456 2012-07-23 17:35:51
好吧,如果你分享瞭如何在其他語言中使用這些信息,我們可以指出你如何在CF中實現這一目標的正確方向。 – Sharondio 2012-07-24 01:13:47