我有一个需要与C#应用程序交谈的SOAP服务。我有一个PHP测试应用程序,它使用标准的SoapClient来使用相同的SOAP服务。
它的使用类似于:
$options = array(
'login' => $username,
'password' => $password,
'location' => "https://$serveruri/soap",
);
$service = new SOAPClient($wsdl, $options);
$retval = $service->SomeMethod($parameter);
这很好用。据我所知(我在PHP上没用),因为我们没有设置身份验证选项,所以应该使用基本身份验证。
我正在尝试与C#中的同一端点进行通信,并且它一直提示我进行身份验证。我不知道如何重新创建相同的身份验证。我相信一些问题来自于使用https - 我过去能够使用http和BasicHttpBinding与类似的系统进行交谈,但由于我必须通过https与这个系统进行对话,这是不行的。
所以我使用SvcUtil生成了一个客户端代理,我正在尝试与之交谈。这是我目前的绝望迭代:
var endpoint = new EndpointAddress(SoapUrl);
var binding = new WSHttpBinding(SecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
binding.SendTimeout = new TimeSpan(0, 0, 10);
ServicePointManager.ServerCertificateValidationCallback +=
(sender, cert, chain, sslPolicyErrors) => true;
var client = new soapServiceClient(binding, endpoint);
if (client.ClientCredentials != null)
{
client.ClientCredentials.UserName.UserName = Settings.AuthenticationUsername;
client.ClientCredentials.UserName.Password = Settings.AuthenticationPassword;
}
var retval = client.SomeMethod(parameter);
并解决Jons的评论如下:client.ClientCredentials在我运行时确实不是null。 ReSharper把它放在那里以阻止自己唠叨。
当我运行时,我从服务器获得401 Unauthorized。我在Visual Studio 2013中获得以下内容:
附加信息:HTTP请求未经授权,客户端身份验证方案为“基本”。从服务器收到的身份验证标头是'Basic realm =“bla bla service”'。
在这种情况下,如何让WCF像PHPs SOAPClient一样?
我应该使用另一种绑定吗?我尝试过不同的SecurityMode值,我尝试过Digest身份验证,但是他们让我无处可去。由于这发生在https上,我想我无法将Wireshark发生..
感谢任何见解!
编辑:Jon建议尝试Fiddler2。我打开了https解密并试一试。
有两件事突然袭来我:
1)当我在本地运行PHP脚本(使用在我的机器上运行的EasyPHP)时,它会联系SOAP服务器并获取数据。但是,Fiddler2没有以任何方式看到这种流量。
2)当我在Visual Studio 2013中运行我的应用程序时,Fiddler2 会看到流量,并对其进行解密。我看到两次尝试联系SOAP端点;两者都获得401回复。第一个没有auth信息(查看Inspectors - > Fiddler2的Auth部分)并且只是说:
没有代理授权标头。
没有授权标题。
然后第二个请求尝试使用看起来像这样的Authorization标头修复它:
授权标题存在:基本[一些哈希数据] 解码用户名:密码= [正确用户名]:[正确密码]
但如上所述 - 这仍然引发了另一方的401。
我不知道为什么PHP流量不会出现在Fiddler2中,但它非常清楚地从另一方接收实时数据。也许PHP不会以Fiddler2可以接收的方式使用网络堆栈,我不知道。
编辑2 :在PHP端进行了一系列肮脏的调试后,我终于将PHP应用程序的请求/响应周期与WCF进行了比较。这让我更加接近(不知何故,我在auth用户名中得到了一个子字符,这导致了身份验证问题),但现在我正在努力解决由于我的绑定被设置为Content-Type application / soap + xml引起的ProtocolException和外部服务(我相信这是基于Linux的)返回text / xml。
我对滥用Google的理解是,text / xml在SOAP 1.1中很常见,而application / soap + xml与SOAP 1.2一起使用。
另外,据我所知,在WCF中,BasicHttpBinding支持SOAP 1.1,而WsHttpBinding支持SOAP 1.2。
由于此服务位于公共互联网上,因此安全性需要https。我相信系统本身的原始SOAP服务使用HTTP,但它位于需要HTTPS的网关后面,然后将其作为HTTP传递给服务请求的实际框。
问题的核心是:我有办法使用带有WCF的HTTPS访问SOAP 1.1服务吗?
答案 0 :(得分:2)
所以我已经完成了这个问题。我今天早上作为WCF新手开始,虽然我甚至声称自己是一个称职的用户,但我对绑定有了更多了解。
通过使用鸟枪调试,我实际上已经正确地完成了几次,但是我被我复制到我的代码中的用户名中的一个看不见的子角色(^ Z我相信)欺骗了。
此外,由于我看到很多关于BasicHttpBinding不支持https的信息,这种情况更加复杂 - 如果您按照这样创建它,它会这样做:
var binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
相信这篇相对较旧的文章,教育我将其弄清楚:
https://msdn.microsoft.com/en-us/magazine/cc163394.aspx
从这篇文章中我也了解到BasicHttpBinding不支持https,我可以构建自己的CustomBinding,只需相对较少的努力即可。
还要感谢我们的霸主Jon Skeet让我朝着正确的方向努力,弄清楚实际上是通过电线发送的是什么!