【发布时间】:2017-08-16 09:06:08
【问题描述】:
我需要通过 XML 与 WebService 进行通信。该服务使用 saml:Assertion 来验证连接。我可以与服务器通信,但验证总是失败。我搜索了几个小时问题出在哪里,因为当我使用具有完全相同参数和 saml 票证的soapUI 时,它可以工作。我尝试“手动”从 saml:Assertion 中删除任何格式,因为它已签名,因此单字节更改将不再有效。
这是我的代码:
// Insert saml:Assertion string into soapenv:Header
private static void InsertSAML(ref XmlDocument soapXML, ref XmlNamespaceManager nsmgr, string saml)
{
// Remove all formatting
saml = saml.Replace("\r", "");
saml = saml.Replace("\n", "");
while(saml.IndexOf(" ") > -1)
{
saml = saml.Replace(" ", " ");
}
saml = saml.Replace("> <", "><");
saml = saml.Replace("\" />", "\"/>");
XmlElement soapHeader = (XmlElement)soapXML.SelectSingleNode("//soapenv:Envelope/soapenv:Header/wsse:Security", nsmgr);
if (soapHeader == null)
{
throw new Exception("Can't find \"//soapenv:Envelope/soapenv:Header/wsse:Security\"");
}
soapHeader.InnerXml += saml;
}
但是当我使用soapHeader.InnerXml += saml; 时,它似乎会导致某种格式。没有内容的元素的结束标签前会出现一个空格:
所以,我需要添加这个:
<dsig:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
但在最终的 XML 中看起来像这样,即使我在插入之前替换了这些出现:
<dsig:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
我怎样才能摆脱这种行为?
【问题讨论】:
-
你为什么认为是格式化失败了?使用诸如wireshark 或fiddler 之类的嗅探器并将soapUI 响应与您的应用程序响应进行比较。它们使您的应用程序看起来像soapUI。首先比较第一个请求并修改您的 c# 代码,以便标头与soapUI 相同。
-
一定是格式。来自soapUI 和我的C# 代码的请求具有完全相同的标题和正文,除了关闭( /> )单个标签之前的空格。
-
如果标题和正文相同,您将如何调用格式?第一反应是一样的吗?都使用http 1.0吗?您是否获得了 200 完成状态?如果数据完全相同,我认为这将是一个时间问题。 http 使用 tcp 作为传输层,可能存在 tcp 断开连接。但我不这么认为。这更像是您同时打开了两个连接,而服务器不允许第二个连接。
-
我从 WebService 得到了明确的响应。没有连接问题,请求已发送,并从我要访问的服务器收到响应。问题是,我收到一条错误消息(来自该服务器的编码响应),表明我的 saml 无效。这是真的,我的 saml:Assertion 不能有效,其中有额外的空格。 saml 是一个签名的指纹,如果一个字节被修改,它就不再有效。我只想知道如何在没有额外空格的情况下将它插入到我的 xml 中。
-
必须在对正文进行所有编辑后进行签名。空间和返回应该被加密然后解密并且不应该有任何区别。所以我不知道你为什么要删除空格。您在 c# 中使用的加密(签名)方法与服务器使用的解密不同。
标签: c# xml formatting saml xmldocument