我正在尝试连接到使用 WS-Security(用户名 + 密码(的服务来保护自己。我正在从 ColdFusion 2016 连接。
我的代码目前如下所示:
<cfxml variable="securityHeaders">
<wsse:Security soapenv:mustUnderstand="1" 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">
<wsse:UsernameToken wsu:Id="UsernameToken-65" 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">
<wsse:Username>myusername</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">mypassword</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">1vrSoBRiARpSIXvhXExgqg==</wsse:Nonce>
<wsu:Created>2017-07-07T20:07:22.041Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</cfxml>
<cfscript>
ws = createObject("webservice", #wsurl#,{wsversion="2",refreshWSDL=true});
WriteDump(#securityHeaders#);
AddSoapRequestHeader(ws, "","",#securityHeaders#,true);
version = ws.GetVersion();
</cfscript>
但是,ColdFusion似乎不喜欢我的XML。我收到此错误:
An error occurred while Parsing an XML document.
The prefix "soapenv" for attribute "soapenv:mustUnderstand" associated with an element type "wsse:Security" is not bound.
The error occurred in C:/ColdFusion2016/cfusion/wwwroot/test/getVersion.cfm: line 12
10 : </cfif>
11 :
12 : <cfxml variable="securityHeaders">
13 : <wsse:Security soapenv:mustUnderstand="1" 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">
14 : <wsse:UsernameToken wsu:Id="UsernameToken-65" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
如果我删除 soapenv:mustUnderstand="1",那么我会收到一个不同的错误,但我的理解是它需要在那里。我在这个 XML 中做错了什么吗?有没有理由它不知道soapenv:mustUnderstand?
任何见解将不胜感激 - 谢谢大家的时间。
编辑 1此更改修复了以下问题:
<wsse:Security soapenv:mustUnderstand="1" 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" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
但现在我收到以下内容:
Cannot perform web service invocation GetVersion.
The fault returned when invoking the web service operation is:
AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}MustUnderstand
faultSubcode:
faultString: Did not understand "MustUnderstand" header(s):
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}stackTrace:
at org.apache.axis.handlers.soap.MustUnderstandChecker.invoke(MustUnderstandChecker.java:96)
at org.apache.axis.client.AxisClient.invoke(AxisClient.java:206)
at org.apache.axis.client.Call.invokeEngine(Call.java:2765)
at org.apache.axis.client.Call.invoke(Call.java:2748)
at org.apache.axis.client.Call.invoke(Call.java:2424)
at org.apache.axis.client.Call.invoke(Call.java:2347)
at org.apache.axis.client.Call.invoke(Call.java:1804)
这是一个工作信封:
<soapenv:Envelope xmlns:abc="ABCService" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header><wsse:Security soapenv:mustUnderstand="1"
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">
<wsse:UsernameToken wsu:Id="UsernameToken-41D8D78B82FF48D24D149946784898124">
<wsse:Username>usernamegoeshere</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">passgoeshere</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">noncehere</wsse:Nonce>
<wsu:Created>2017-07-07T22:50:48.980Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security></soapenv:Header>
<soapenv:Body>
<abc:GetVersion/>
</soapenv:Body>
</soapenv:Envelope>
这是我可以从跟踪中看到的失败信封(我不确定 CF2016/轴是否因请求或结果而窒息(
<MessageHeaders>
<wsse:Security soapenv:mustUnderstand="1" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 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" soapenv:actor="">
<wsse:UsernameToken wsu:Id="UsernameToken-65" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>
<!-- Removed-->
</wsse:Username>
<wsse:Password>
<!-- Removed-->
</wsse:Password>
<wsse:Nonce>
<!-- Removed-->
</wsse:Nonce>
<wsu:Created>2017-07-07T20:35:22.041Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
<To d4p1:mustUnderstand="1" xmlns:d4p1="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">https://pc/Service/Service.svc</To>
<Action d4p1:mustUnderstand="1" xmlns:d4p1="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">Service/Service/GetVersion</Action>
</MessageHeaders>
在我的跟踪中 - 我可以看到它"通过通道接收消息,安全协议验证消息,消息被读取,我看到 GetVersion 执行到/从,然后我看到传出消息。轴在接收消息时是否有可能失败?
好的,所以它归结为 WCF 和 Coldfusion 交互的方式。在这种情况下,请求命中服务器,安讯士无法理解响应。
在 SOAPUI 中,响应将时间戳标头/标签设置为必须理解。使用基本 httpbinding 时,此标头将添加到 WCF 中。客户端无法理解此标头,因此会窒息。
解决方案是移动到自定义绑定,以便在安全节点上将 includeTimestamp 设置为 false。
绑定配置
<bindings>
<customBinding>
<binding name="myCustomBinding">
<security authenticationMode="UserNameOverTransport" includeTimestamp="false">
<secureConversationBootstrap/>
</security>
<textMessageEncoding messageVersion="Soap12">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</textMessageEncoding>
<httpsTransport></httpsTransport>
</binding>
</customBinding>
服务配置:
<services>
<service behaviorConfiguration="MyBehavior" name="MyNamespace.MyService">
<endpoint address="" binding="customBinding" bindingConfiguration="myCustomBinding"
bindingNamespace="MyNamespace" contract="MyNameSpace.IMyService" />
然后响应如下所示(请注意没有时间戳标记(:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Body>
<GetVersionResponse xmlns="MyNamespace">
<GetVersionResult>1.0</GetVersionResult>
</GetVersionResponse>
</s:Body>
</s:Envelope>
我的冷融合代码看起来像这样:
<cfxml variable="securityHeaders" casesensitive="true">
<wsse:Security soapenv:mustUnderstand="1" 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" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<wsse:UsernameToken wsu:Id="UsernameToken-65" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>usernamegoeshere</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">passgoeshere</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">1vrSoBRiARpSIXvhXExgqg==</wsse:Nonce>
<wsu:Created>2017-07-07T20:35:22.041Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</cfxml>
<cfscript>
ws = createObject("webservice", #wsurl#);
//WriteDump(#securityHeaders#);
AddSoapRequestHeader(ws, "dummy","dummy",#securityHeaders#,true);
version = ws.GetVersion();
WriteOutput(version);
</cfscript>